diff options
Diffstat (limited to 'frontends/ast')
-rw-r--r-- | frontends/ast/ast.cc | 147 | ||||
-rw-r--r-- | frontends/ast/ast.h | 10 | ||||
-rw-r--r-- | frontends/ast/genrtlil.cc | 1 | ||||
-rw-r--r-- | frontends/ast/simplify.cc | 152 |
4 files changed, 240 insertions, 70 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 82283fb5b..5bbea0faf 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -158,7 +158,14 @@ std::string AST::type2str(AstNodeType type) X(AST_POSEDGE) X(AST_NEGEDGE) X(AST_EDGE) + X(AST_INTERFACE) + X(AST_INTERFACEPORT) + X(AST_INTERFACEPORTTYPE) + X(AST_MODPORT) + X(AST_MODPORTMEMBER) X(AST_PACKAGE) + X(AST_WIRETYPE) + X(AST_TYPEDEF) #undef X default: log_abort(); @@ -201,6 +208,7 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch was_checked = false; range_valid = false; range_swapped = false; + is_custom_type = false; port_id = 0; range_left = -1; range_right = 0; @@ -1099,6 +1107,13 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast ignoreThisSignalsInInitial = RTLIL::SigSpec(); } + else { + for (auto &attr : ast->attributes) { + if (attr.second->type != AST_CONSTANT) + continue; + current_module->attributes[attr.first] = attr.second->asAttrConst(); + } + } if (ast->type == AST_INTERFACE) current_module->set_bool_attribute("\\is_interface"); @@ -1284,6 +1299,8 @@ void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule // from AST. The interface members are copied into the AST module with the prefix of the interface. void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module*> local_interfaces) { + loadconfig(); + bool is_top = false; AstNode *new_ast = ast->clone(); for (auto &intf : local_interfaces) { @@ -1368,10 +1385,10 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT // create a new parametric module (when needed) and return the name of the generated module - WITH support for interfaces // This method is used to explode the interface when the interface is a port of the module (not instantiated inside) -RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail) +RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool /*mayfail*/) { AstNode *new_ast = NULL; - std::string modname = derive_common(design, parameters, &new_ast, mayfail); + std::string modname = derive_common(design, parameters, &new_ast); // Since interfaces themselves may be instantiated with different parameters, // "modname" must also take those into account, so that unique modules @@ -1384,11 +1401,17 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R has_interfaces = true; } + std::string new_modname = modname; if (has_interfaces) - modname += "$interfaces$" + interf_info; + new_modname += "$interfaces$" + interf_info; - if (!design->has(modname)) { + if (!design->has(new_modname)) { + if (!new_ast) { + auto mod = dynamic_cast<AstModule*>(design->module(modname)); + new_ast = mod->ast->clone(); + } + modname = new_modname; new_ast->str = modname; // Iterate over all interfaces which are ports in this module: @@ -1441,10 +1464,10 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R } // create a new parametric module (when needed) and return the name of the generated module - without support for interfaces -RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail) +RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool /*mayfail*/) { AstNode *new_ast = NULL; - std::string modname = derive_common(design, parameters, &new_ast, mayfail); + std::string modname = derive_common(design, parameters, &new_ast); if (!design->has(modname)) { new_ast->str = modname; @@ -1459,64 +1482,75 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R } // create a new parametric module (when needed) and return the name of the generated module -std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool) +std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out) { std::string stripped_name = name.str(); if (stripped_name.compare(0, 9, "$abstract") == 0) stripped_name = stripped_name.substr(9); - log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); - - current_ast = NULL; - flag_dump_ast1 = false; - flag_dump_ast2 = false; - flag_dump_vlog1 = false; - flag_dump_vlog2 = false; - flag_nolatches = nolatches; - flag_nomeminit = nomeminit; - flag_nomem2reg = nomem2reg; - flag_mem2reg = mem2reg; - flag_noblackbox = noblackbox; - flag_lib = lib; - flag_nowb = nowb; - flag_noopt = noopt; - flag_icells = icells; - flag_pwires = pwires; - flag_autowire = autowire; - use_internal_line_num(); - std::string para_info; - AstNode *new_ast = ast->clone(); int para_counter = 0; - int orig_parameters_n = parameters.size(); - for (auto it = new_ast->children.begin(); it != new_ast->children.end(); it++) { - AstNode *child = *it; + for (const auto child : ast->children) { if (child->type != AST_PARAMETER) continue; para_counter++; std::string para_id = child->str; if (parameters.count(para_id) > 0) { log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str]))); - rewrite_parameter: para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); - delete child->children.at(0); - if ((parameters[para_id].flags & RTLIL::CONST_FLAG_REAL) != 0) { - child->children[0] = new AstNode(AST_REALVALUE); - child->children[0]->realvalue = std::stod(parameters[para_id].decode_string()); - } else if ((parameters[para_id].flags & RTLIL::CONST_FLAG_STRING) != 0) - child->children[0] = AstNode::mkconst_str(parameters[para_id].decode_string()); - else - child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0); - parameters.erase(para_id); continue; } para_id = stringf("$%d", para_counter); if (parameters.count(para_id) > 0) { log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); + para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); + continue; + } + } + + std::string modname; + if (parameters.size() == 0) + modname = stripped_name; + else if (para_info.size() > 60) + modname = "$paramod$" + sha1(para_info) + stripped_name; + else + modname = "$paramod" + stripped_name + para_info; + + if (design->has(modname)) + return modname; + + log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); + loadconfig(); + + AstNode *new_ast = ast->clone(); + para_counter = 0; + for (auto child : new_ast->children) { + if (child->type != AST_PARAMETER) + continue; + para_counter++; + std::string para_id = child->str; + if (parameters.count(para_id) > 0) { + log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str]))); goto rewrite_parameter; } + para_id = stringf("$%d", para_counter); + if (parameters.count(para_id) > 0) { + log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); + goto rewrite_parameter; + } + continue; + rewrite_parameter: + delete child->children.at(0); + if ((parameters[para_id].flags & RTLIL::CONST_FLAG_REAL) != 0) { + child->children[0] = new AstNode(AST_REALVALUE); + child->children[0]->realvalue = std::stod(parameters[para_id].decode_string()); + } else if ((parameters[para_id].flags & RTLIL::CONST_FLAG_STRING) != 0) + child->children[0] = AstNode::mkconst_str(parameters[para_id].decode_string()); + else + child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0); + parameters.erase(para_id); } for (auto param : parameters) { @@ -1529,16 +1563,6 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString new_ast->children.push_back(defparam); } - std::string modname; - - if (orig_parameters_n == 0) - modname = stripped_name; - else if (para_info.size() > 60) - modname = "$paramod$" + sha1(para_info) + stripped_name; - else - modname = "$paramod" + stripped_name + para_info; - - (*new_ast_out) = new_ast; return modname; } @@ -1565,6 +1589,27 @@ RTLIL::Module *AstModule::clone() const return new_mod; } +void AstModule::loadconfig() const +{ + current_ast = NULL; + flag_dump_ast1 = false; + flag_dump_ast2 = false; + flag_dump_vlog1 = false; + flag_dump_vlog2 = false; + flag_nolatches = nolatches; + flag_nomeminit = nomeminit; + flag_nomem2reg = nomem2reg; + flag_mem2reg = mem2reg; + flag_noblackbox = noblackbox; + flag_lib = lib; + flag_nowb = nowb; + flag_noopt = noopt; + flag_icells = icells; + flag_pwires = pwires; + flag_autowire = autowire; + use_internal_line_num(); +} + // internal dummy line number callbacks namespace { int internal_line_num; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 54b2fb319..918d178c7 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -148,7 +148,10 @@ namespace AST AST_INTERFACEPORTTYPE, AST_MODPORT, AST_MODPORTMEMBER, - AST_PACKAGE + AST_PACKAGE, + + AST_WIRETYPE, + AST_TYPEDEF }; // convert an node type to a string (e.g. for debug output) @@ -174,7 +177,7 @@ namespace AST // node content - most of it is unused in most node types std::string str; std::vector<RTLIL::State> bits; - bool is_input, is_output, is_reg, is_logic, is_signed, is_string, is_wand, is_wor, range_valid, range_swapped, was_checked, is_unsized; + bool is_input, is_output, is_reg, is_logic, is_signed, is_string, is_wand, is_wor, range_valid, range_swapped, was_checked, is_unsized, is_custom_type; int port_id, range_left, range_right; uint32_t integer; double realvalue; @@ -296,9 +299,10 @@ namespace AST ~AstModule() YS_OVERRIDE; RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail) YS_OVERRIDE; RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail) YS_OVERRIDE; - std::string derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool mayfail); + std::string derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out); void reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module *> local_interfaces) YS_OVERRIDE; RTLIL::Module *clone() const YS_OVERRIDE; + void loadconfig() const; }; // this must be set by the language frontend before parsing the sources diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 407a34472..94f5c0a04 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -863,6 +863,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_PACKAGE: case AST_MODPORT: case AST_MODPORTMEMBER: + case AST_TYPEDEF: break; case AST_INTERFACEPORT: { // If a port in a module with unknown type is found, mark it with the attribute 'is_interface' diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 86dd80c65..44fd32cdc 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -318,7 +318,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } // activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.) - if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX) + if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX || type == AST_TYPEDEF) const_fold = true; if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM)) const_fold = true; @@ -336,6 +336,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, std::map<std::string, AstNode*> this_wire_scope; for (size_t i = 0; i < children.size(); i++) { AstNode *node = children[i]; + if (node->type == AST_WIRE) { if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) { for (auto c : node->children[0]->children) { @@ -405,14 +406,15 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, this_wire_scope[node->str] = node; } if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR || - node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION || node->type == AST_CELL) { + node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION || node->type == AST_CELL || + node->type == AST_TYPEDEF) { backup_scope[node->str] = current_scope[node->str]; current_scope[node->str] = node; } } for (size_t i = 0; i < children.size(); i++) { AstNode *node = children[i]; - if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY) + if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY || node->type == AST_TYPEDEF) while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM)) did_something = true; } @@ -780,6 +782,99 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, delete_children(); } + // resolve typedefs + if (type == AST_TYPEDEF) { + log_assert(children.size() == 1); + log_assert(children[0]->type == AST_WIRE || children[0]->type == AST_MEMORY); + while(children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) + did_something = true; + log_assert(!children[0]->is_custom_type); + } + + // resolve types of wires + if (type == AST_WIRE || type == AST_MEMORY) { + if (is_custom_type) { + log_assert(children.size() >= 1); + log_assert(children[0]->type == AST_WIRETYPE); + if (!current_scope.count(children[0]->str)) + log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[0]->str.c_str()); + AstNode *resolved_type = current_scope.at(children[0]->str); + if (resolved_type->type != AST_TYPEDEF) + log_file_error(filename, linenum, "`%s' does not name a type\n", children[0]->str.c_str()); + log_assert(resolved_type->children.size() == 1); + AstNode *templ = resolved_type->children[0]; + // Remove type reference + delete children[0]; + children.erase(children.begin()); + + // Ensure typedef itself is fully simplified + while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; + + if (type == AST_WIRE) + type = templ->type; + is_reg = templ->is_reg; + is_logic = templ->is_logic; + is_signed = templ->is_signed; + is_string = templ->is_string; + is_custom_type = templ->is_custom_type; + + range_valid = templ->range_valid; + range_swapped = templ->range_swapped; + range_left = templ->range_left; + range_right = templ->range_right; + + // Insert clones children from template at beginning + for (int i = 0; i < GetSize(templ->children); i++) + children.insert(children.begin() + i, templ->children[i]->clone()); + + if (type == AST_MEMORY && GetSize(children) == 1) { + // Single-bit memories must have [0:0] range + AstNode *rng = new AstNode(AST_RANGE); + rng->children.push_back(AstNode::mkconst_int(0, true)); + rng->children.push_back(AstNode::mkconst_int(0, true)); + children.insert(children.begin(), rng); + } + + did_something = true; + } + log_assert(!is_custom_type); + } + + // resolve types of parameters + if (type == AST_LOCALPARAM || type == AST_PARAMETER) { + if (is_custom_type) { + log_assert(children.size() == 2); + log_assert(children[1]->type == AST_WIRETYPE); + if (!current_scope.count(children[1]->str)) + log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[1]->str.c_str()); + AstNode *resolved_type = current_scope.at(children[1]->str); + if (resolved_type->type != AST_TYPEDEF) + log_file_error(filename, linenum, "`%s' does not name a type\n", children[1]->str.c_str()); + log_assert(resolved_type->children.size() == 1); + AstNode *templ = resolved_type->children[0]; + delete children[1]; + children.pop_back(); + + // Ensure typedef itself is fully simplified + while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; + + if (templ->type == AST_MEMORY) + log_file_error(filename, linenum, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str()); + is_signed = templ->is_signed; + is_string = templ->is_string; + is_custom_type = templ->is_custom_type; + + range_valid = templ->range_valid; + range_swapped = templ->range_swapped; + range_left = templ->range_left; + range_right = templ->range_right; + for (auto template_child : templ->children) + children.push_back(template_child->clone()); + did_something = true; + } + log_assert(!is_custom_type); + } + // resolve constant prefixes if (type == AST_PREFIX) { if (children[0]->type != AST_CONSTANT) { @@ -1194,7 +1289,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_BLOCK && str.empty()) { for (size_t i = 0; i < children.size(); i++) - if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM) + if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM || children[i]->type == AST_TYPEDEF) log_file_error(children[i]->filename, children[i]->linenum, "Local declaration in unnamed block is an unsupported SystemVerilog feature!\n"); } @@ -1206,7 +1301,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, std::vector<AstNode*> new_children; for (size_t i = 0; i < children.size(); i++) - if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM) { + if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM || children[i]->type == AST_TYPEDEF) { children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(children[i]); current_scope[children[i]->str] = children[i]; @@ -1530,10 +1625,16 @@ skip_dynamic_range_lvalue_expansion:; current_scope[wire_en->str] = wire_en; while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } - std::vector<RTLIL::State> x_bit; - x_bit.push_back(RTLIL::State::Sx); + AstNode *check_defval; + if (type == AST_LIVE || type == AST_FAIR) { + check_defval = new AstNode(AST_REDUCE_BOOL, children[0]->clone()); + } else { + std::vector<RTLIL::State> x_bit; + x_bit.push_back(RTLIL::State::Sx); + check_defval = mkconst_bits(x_bit, false); + } - AstNode *assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bit, false)); + AstNode *assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), check_defval); assign_check->children[0]->str = id_check; assign_check->children[0]->was_checked = true; @@ -1546,9 +1647,13 @@ skip_dynamic_range_lvalue_expansion:; default_signals->children.push_back(assign_en); current_top_block->children.insert(current_top_block->children.begin(), default_signals); - assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), new AstNode(AST_REDUCE_BOOL, children[0]->clone())); - assign_check->children[0]->str = id_check; - assign_check->children[0]->was_checked = true; + if (type == AST_LIVE || type == AST_FAIR) { + assign_check = nullptr; + } else { + assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), new AstNode(AST_REDUCE_BOOL, children[0]->clone())); + assign_check->children[0]->str = id_check; + assign_check->children[0]->was_checked = true; + } if (current_always == nullptr || current_always->type != AST_INITIAL) { assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(1, false, 1)); @@ -1560,7 +1665,8 @@ skip_dynamic_range_lvalue_expansion:; assign_en->children[0]->was_checked = true; newNode = new AstNode(AST_BLOCK); - newNode->children.push_back(assign_check); + if (assign_check != nullptr) + newNode->children.push_back(assign_check); newNode->children.push_back(assign_en); AstNode *assertnode = new AstNode(type); @@ -2884,11 +2990,18 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m void AstNode::expand_genblock(std::string index_var, std::string prefix, std::map<std::string, std::string> &name_map) { if (!index_var.empty() && type == AST_IDENTIFIER && str == index_var) { - current_scope[index_var]->children[0]->cloneInto(this); - return; + if (children.empty()) { + current_scope[index_var]->children[0]->cloneInto(this); + } else { + AstNode *p = new AstNode(AST_LOCALPARAM, current_scope[index_var]->children[0]->clone()); + p->str = stringf("$genval$%d", autoidx++); + current_ast_mod->children.push_back(p); + str = p->str; + id2ast = p; + } } - if ((type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL) && name_map.count(str) > 0) + if ((type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL || type == AST_WIRETYPE) && name_map.count(str) > 0) str = name_map[str]; std::map<std::string, std::string> backup_name_map; @@ -2896,7 +3009,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma for (size_t i = 0; i < children.size(); i++) { AstNode *child = children[i]; if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER || child->type == AST_LOCALPARAM || - child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL) { + child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL || child->type == AST_TYPEDEF) { if (backup_name_map.size() == 0) backup_name_map = name_map; std::string new_name = prefix[0] == '\\' ? prefix.substr(1) : prefix; @@ -2927,6 +3040,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma child->expand_genblock(index_var, prefix, name_map); } + if (backup_name_map.size() > 0) name_map.swap(backup_name_map); } @@ -2980,6 +3094,9 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg uint32_t children_flags = 0; int lhs_children_counter = 0; + if (type == AST_TYPEDEF) + return; // don't touch content of typedefs + if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) { // mark all memories that are used in a complex expression on the left side of an assignment @@ -3137,6 +3254,9 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, if (type == AST_FUNCTION || type == AST_TASK) return false; + if (type == AST_TYPEDEF) + return false; + if (type == AST_MEMINIT && id2ast && mem2reg_set.count(id2ast)) { log_assert(children[0]->type == AST_CONSTANT); |