diff options
Diffstat (limited to 'frontends/ast/ast.cc')
-rw-r--r-- | frontends/ast/ast.cc | 82 |
1 files changed, 65 insertions, 17 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index d35ea4171..2c552ea22 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -46,11 +46,12 @@ namespace AST { // instanciate global variables (private API) namespace AST_INTERNAL { - bool flag_dump_ast, flag_dump_ast_diff, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg; + bool flag_dump_ast, flag_dump_ast_diff, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib; AstNode *current_ast, *current_ast_mod; std::map<std::string, AstNode*> current_scope; RTLIL::SigSpec *genRTLIL_subst_from = NULL; RTLIL::SigSpec *genRTLIL_subst_to = NULL; + RTLIL::SigSpec ignoreThisSignalsInInitial; AstNode *current_top_block, *current_block, *current_block_child; AstModule *current_module; } @@ -122,6 +123,7 @@ std::string AST::type2str(AstNodeType type) X(AST_CELL) X(AST_PRIMITIVE) X(AST_ALWAYS) + X(AST_INITIAL) X(AST_BLOCK) X(AST_ASSIGN_EQ) X(AST_ASSIGN_LE) @@ -417,6 +419,14 @@ void AstNode::dumpVlog(FILE *f, std::string indent) } break; + case AST_INITIAL: + fprintf(f, "%s" "initial\n", indent.c_str()); + for (auto child : children) { + if (child->type != AST_POSEDGE && child->type != AST_NEGEDGE && child->type != AST_EDGE) + child->dumpVlog(f, indent + " "); + } + break; + case AST_POSEDGE: case AST_NEGEDGE: case AST_EDGE: @@ -679,10 +689,25 @@ static AstModule* process_module(AstNode *ast) log("--- END OF AST DUMP ---\n"); } + if (flag_lib) { + std::vector<AstNode*> new_children; + for (auto child : ast->children) { + if (child->type == AST_WIRE && (child->is_input || child->is_output)) + new_children.push_back(child); + else + delete child; + } + ast->children.swap(new_children); + ast->attributes["\\placeholder"] = AstNode::mkconst_int(0, false, 0); + } + current_module = new AstModule; current_module->ast = NULL; current_module->name = ast->str; current_module->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum); + + ignoreThisSignalsInInitial = RTLIL::SigSpec(); + for (auto &attr : ast->attributes) { if (attr.second->type != AST_CONSTANT) log_error("Attribute `%s' with non-constant value at %s:%d!\n", @@ -697,19 +722,30 @@ static AstModule* process_module(AstNode *ast) } for (size_t i = 0; i < ast->children.size(); i++) { AstNode *node = ast->children[i]; - if (node->type != AST_WIRE && node->type != AST_MEMORY) + if (node->type != AST_WIRE && node->type != AST_MEMORY && node->type != AST_INITIAL) node->genRTLIL(); } + ignoreThisSignalsInInitial.sort_and_unify(); + + for (size_t i = 0; i < ast->children.size(); i++) { + AstNode *node = ast->children[i]; + if (node->type == AST_INITIAL) + node->genRTLIL(); + } + + ignoreThisSignalsInInitial = RTLIL::SigSpec(); + current_module->ast = ast_before_simplify; current_module->nolatches = flag_nolatches; current_module->nomem2reg = flag_nomem2reg; current_module->mem2reg = flag_mem2reg; + current_module->lib = flag_lib; return current_module; } // create AstModule instances for all modules in the AST tree and add them to 'design' -void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast, bool dump_ast_diff, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg) +void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast, bool dump_ast_diff, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib) { current_ast = ast; flag_dump_ast = dump_ast; @@ -718,6 +754,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast, bool dump_ flag_nolatches = nolatches; flag_nomem2reg = nomem2reg; flag_mem2reg = mem2reg; + flag_lib = lib; assert(current_ast->type == AST_DESIGN); for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) { @@ -747,8 +784,10 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map<RTLIL::IdStrin flag_nolatches = nolatches; flag_nomem2reg = nomem2reg; flag_mem2reg = mem2reg; + flag_lib = lib; use_internal_line_num(); + std::string para_info; std::vector<unsigned char> hash_data; hash_data.insert(hash_data.end(), name.begin(), name.end()); hash_data.push_back(0); @@ -762,9 +801,10 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map<RTLIL::IdStrin continue; para_counter++; std::string para_id = child->str; - if (parameters.count(child->str) > 0) { + 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]))); child->delete_children(); child->children.push_back(AstNode::mkconst_bits(parameters[para_id].bits, false)); hash_data.insert(hash_data.end(), child->str.begin(), child->str.end()); @@ -774,10 +814,8 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map<RTLIL::IdStrin parameters.erase(para_id); continue; } - char buf[100]; - snprintf(buf, 100, "$%d", para_counter); - if (parameters.count(buf) > 0) { - para_id = buf; + 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; } @@ -785,17 +823,26 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map<RTLIL::IdStrin if (parameters.size() > 0) log_error("Requested parameter `%s' does not exist in module `%s'!\n", parameters.begin()->first.c_str(), name.c_str()); - unsigned char hash[20]; - unsigned char *hash_data2 = new unsigned char[hash_data.size()]; - for (size_t i = 0; i < hash_data.size(); i++) - hash_data2[i] = hash_data[i]; - sha1::calc(hash_data2, hash_data.size(), hash); - delete[] hash_data2; + std::string modname; + + if (para_info.size() > 60) + { + unsigned char hash[20]; + unsigned char *hash_data2 = new unsigned char[hash_data.size()]; + for (size_t i = 0; i < hash_data.size(); i++) + hash_data2[i] = hash_data[i]; + sha1::calc(hash_data2, hash_data.size(), hash); + delete[] hash_data2; - char hexstring[41]; - sha1::toHexString(hash, hexstring); + char hexstring[41]; + sha1::toHexString(hash, hexstring); - std::string modname = "$paramod$" + std::string(hexstring) + "$" + name; + modname = "$paramod$" + std::string(hexstring) + name; + } + else + { + modname = "$paramod" + name + para_info; + } if (design->modules.count(modname) == 0) { new_ast->str = modname; @@ -821,6 +868,7 @@ void AstModule::update_auto_wires(std::map<RTLIL::IdString, int> auto_sizes) flag_nolatches = nolatches; flag_nomem2reg = nomem2reg; flag_mem2reg = mem2reg; + flag_lib = lib; use_internal_line_num(); for (auto it = auto_sizes.begin(); it != auto_sizes.end(); it++) { |