From 3aa4484a3cd9a2e82fddd499cde575eaf8c565cc Mon Sep 17 00:00:00 2001 From: Henner Zeller Date: Fri, 20 Jul 2018 23:41:18 -0700 Subject: Consistent use of 'override' for virtual methods in derived classes. o Not all derived methods were marked 'override', but it is a great feature of C++11 that we should make use of. o While at it: touched header files got a -*- c++ -*- for emacs to provide support for that language. o use YS_OVERRIDE for all override keywords (though we should probably use the plain keyword going forward now that C++11 is established) --- passes/hierarchy/hierarchy.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index e61851481..5df69848e 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -343,7 +343,7 @@ int find_top_mod_score(Design *design, Module *module, dict &db) struct HierarchyPass : public Pass { HierarchyPass() : Pass("hierarchy", "check, expand and clean up design hierarchy") { } - virtual void help() + void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -414,7 +414,7 @@ struct HierarchyPass : public Pass { log("in the current design.\n"); log("\n"); } - virtual void execute(std::vector args, RTLIL::Design *design) + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { log_header(design, "Executing HIERARCHY pass (managing design hierarchy).\n"); -- cgit v1.2.3 From 75009ada3c2a4bcd38c52c8fb871c9e8c1f2e6b1 Mon Sep 17 00:00:00 2001 From: Ruben Undheim Date: Thu, 11 Oct 2018 23:33:31 +0200 Subject: Synthesis support for SystemVerilog interfaces This time doing the changes mostly in AST before RTLIL generation --- passes/hierarchy/hierarchy.cc | 172 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 165 insertions(+), 7 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 5df69848e..dd4341127 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -145,9 +145,24 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check std::map> array_cells; std::string filename; + dict interfaces_in_module; for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; + if(cell->get_bool_attribute("\\is_interface")) { + RTLIL::Module *intf_module = design->modules_[cell->type]; + interfaces_in_module[cell->name] = intf_module; + } + } + + for (auto &cell_it : module->cells_) + { + RTLIL::Cell *cell = cell_it.second; + bool has_interfaces_not_found = false; + + std::vector connections_to_remove; + std::vector connections_to_add_name; + std::vector connections_to_add_signal; if (cell->type.substr(0, 7) == "$array:") { int pos_idx = cell->type.str().find_first_of(':'); @@ -158,6 +173,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check array_cells[cell] = std::pair(idx, num); cell->type = cell->type.str().substr(pos_type + 1); } + dict interfaces_to_add_to_submodule; if (design->modules_.count(cell->type) == 0) { @@ -200,11 +216,61 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check if (design->modules_.count(cell->type) == 0) log_error("File `%s' from libdir does not declare module `%s'.\n", filename.c_str(), cell->type.c_str()); did_something = true; - } else + } else { + + RTLIL::Module *mod = design->module(cell->type); + + // Go over all connections and see if any of them are SV interfaces. If they are, then add the replacements to + // some lists, so that they can be replaced further down: + for (auto &conn : cell->connections()) { + if(mod->wires_.count(conn.first) != 0 && mod->wire(conn.first)->get_bool_attribute("\\is_interface")) { // Check if the connection is present as an interface in the sub-module's port list + if(conn.second.bits().size() == 1 && conn.second.bits()[0].wire->get_bool_attribute("\\is_interface")) { + std::string interface_name_str = conn.second.bits()[0].wire->name.str(); + interface_name_str.replace(0,23,""); + interface_name_str = "\\" + interface_name_str; + RTLIL::IdString interface_name = interface_name_str; + bool will_do_step = false; + if(module->get_bool_attribute("\\interfaces_replaced_in_module")) { + if (interfaces_in_module.count(interface_name) > 0) { // Check if the interface instance is present in module + RTLIL::Module *mod_replace_ports = interfaces_in_module.at(interface_name); + for (auto &mod_wire : mod_replace_ports->wires_) { + std::string signal_name1 = conn.first.str() + "." + log_id(mod_wire.first); + std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire.first); + connections_to_add_name.push_back(RTLIL::IdString(signal_name1)); + if(module->wires_.count(signal_name2) == 0) { + log_error("Could not find signal '%s' in '%s'\n", signal_name2.c_str(), log_id(module->name)); + } + else { + RTLIL::Wire *wire_in_parent = module->wire(signal_name2); + connections_to_add_signal.push_back(wire_in_parent); + } + } + connections_to_remove.push_back(conn.first); + interfaces_to_add_to_submodule[conn.first] = interfaces_in_module.at(interface_name); + } + else will_do_step = true; + } + else will_do_step = true; + // If the interface instance has not already been derived in the module, we cannot complete at this stage. Set "has_interfaces_not_found" + // which will delay the expansion of this cell: + if (will_do_step) { + // If we have already gone over all cells in this module, and the interface has still not been found - flag it as an error: + if(!(module->get_bool_attribute("\\cells_not_processed"))) { + log_warning("Could not find interface instance for `%s' in `%s'\n", log_id(interface_name), log_id(module)); + } + else { + // Only set has_interfaces_not_found if it would be possible to find them, since otherwiser we will end up in an infinite loop: + has_interfaces_not_found = true; + } + } + } + } + } + // + if (flag_check || flag_simcheck) { - RTLIL::Module *mod = design->module(cell->type); - for (auto &conn : cell->connections()) + for (auto &conn : cell->connections()) { if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') { int id = atoi(conn.first.c_str()+1); if (id <= 0 || id > GetSize(mod->ports)) @@ -213,11 +279,15 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check } else if (mod->wire(conn.first) == nullptr || mod->wire(conn.first)->port_id == 0) log_error("Module `%s' referenced in module `%s' in cell `%s' does not have a port named '%s'.\n", log_id(cell->type), log_id(module), log_id(cell), log_id(conn.first)); + } for (auto ¶m : cell->parameters) if (mod->avail_parameters.count(param.first) == 0 && param.first[0] != '$' && strchr(param.first.c_str(), '.') == NULL) log_error("Module `%s' referenced in module `%s' in cell `%s' does not have a parameter named '%s'.\n", log_id(cell->type), log_id(module), log_id(cell), log_id(param.first)); + + } } + RTLIL::Module *mod = design->modules_[cell->type]; if (design->modules_.at(cell->type)->get_bool_attribute("\\blackbox")) { if (flag_simcheck) @@ -226,15 +296,59 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check continue; } - if (cell->parameters.size() == 0) + // If interface instances not yet found, skip cell for now, and say we did something, so that we will return back here: + if(has_interfaces_not_found) { + did_something = true; // waiting for interfaces to be handled continue; + } - RTLIL::Module *mod = design->modules_[cell->type]; - cell->type = mod->derive(design, cell->parameters); + // Do the actual replacements of the SV interface port connection with the individual signal connections: + for(unsigned int i=0;iconnections_[connections_to_add_name[i]] = connections_to_add_signal[i]; + } + // Remove the connection for the interface itself: + for(unsigned int i=0;iconnections_.erase(connections_to_remove[i]); + } + + // If there are no overridden parameters AND not interfaces, then we can use the existing module instance as the type + // for the cell: + if (cell->parameters.size() == 0 && (interfaces_to_add_to_submodule.size() == 0 || !(cell->get_bool_attribute("\\module_not_derived")))) { + // If the cell being processed is an the interface instance itself, go down to "handle_interface_instance:", + // so that the signals of the interface are added to the parent module. + if (mod->get_bool_attribute("\\is_interface")) { + goto handle_interface_instance; + } + continue; + } + + cell->type = mod->derive(design, cell->parameters, interfaces_to_add_to_submodule); cell->parameters.clear(); did_something = true; + + handle_interface_instance: + + // We add all the signals of the interface explicitly to the parent module. This is always needed when we encounter + // an interface instance: + if (mod->get_bool_attribute("\\is_interface") && cell->get_bool_attribute("\\module_not_derived")) { + cell->set_bool_attribute("\\is_interface"); + RTLIL::Module *derived_module = design->modules_[cell->type]; + interfaces_in_module[cell->name] = derived_module; + did_something = true; + } + // We unset 'module_not_derived' such that we will not rederive the cell again (needed when there are interfaces connected to the cell) + cell->attributes.erase("\\module_not_derived"); + } + // Setting a flag such that it can be known that we have been through all cells at least once, such that we can know whether to flag + // an error because of interface instances not found: + module->attributes.erase("\\cells_not_processed"); + + if (interfaces_in_module.size() > 0 && !module->get_bool_attribute("\\interfaces_replaced_in_module")) { + module->reprocess_module(design, interfaces_in_module); + return did_something; } + for (auto &it : array_cells) { RTLIL::Cell *cell = it.first; @@ -341,6 +455,20 @@ int find_top_mod_score(Design *design, Module *module, dict &db) return db.at(module); } +RTLIL::Module *check_if_top_has_changed(Design *design, Module *top_mod) +{ + if(top_mod != NULL && top_mod->get_bool_attribute("\\initial_top")) + return top_mod; + else { + for (auto mod : design->modules()) { + if (mod->get_bool_attribute("\\top")) { + return mod; + } + } + } + return NULL; +} + struct HierarchyPass : public Pass { HierarchyPass() : Pass("hierarchy", "check, expand and clean up design hierarchy") { } void help() YS_OVERRIDE @@ -568,6 +696,14 @@ struct HierarchyPass : public Pass { if (flag_simcheck && top_mod == nullptr) log_error("Design has no top module.\n"); + if (top_mod != NULL) { + for (auto &mod_it : design->modules_) + if (mod_it.second == top_mod) + mod_it.second->attributes["\\initial_top"] = RTLIL::Const(1); + else + mod_it.second->attributes.erase("\\initial_top"); + } + bool did_something = true; while (did_something) { @@ -586,19 +722,41 @@ struct HierarchyPass : public Pass { if (expand_module(design, module, flag_check, flag_simcheck, libdirs)) did_something = true; } + + + RTLIL::Module *tmp_top_mod = check_if_top_has_changed(design, top_mod); + if (tmp_top_mod != NULL) { + if (tmp_top_mod != top_mod){ + top_mod = tmp_top_mod; + did_something = true; + } + } + + std::vector modules_to_delete; + for(auto &mod_it : design->modules_) { + if (mod_it.second->get_bool_attribute("\\to_delete")) { + modules_to_delete.push_back(mod_it.second); + } + } + for(size_t i=0; iremove(modules_to_delete[i]); + } } + if (top_mod != NULL) { log_header(design, "Analyzing design hierarchy..\n"); hierarchy_clean(design, top_mod, purge_lib); } if (top_mod != NULL) { - for (auto &mod_it : design->modules_) + for (auto &mod_it : design->modules_) { if (mod_it.second == top_mod) mod_it.second->attributes["\\top"] = RTLIL::Const(1); else mod_it.second->attributes.erase("\\top"); + mod_it.second->attributes.erase("\\initial_top"); + } } if (!nokeep_asserts) { -- cgit v1.2.3 From 458a94059e6738d93a87ddb9af282d0e1d28791d Mon Sep 17 00:00:00 2001 From: Ruben Undheim Date: Fri, 12 Oct 2018 20:58:37 +0200 Subject: Support for 'modports' for System Verilog interfaces --- passes/hierarchy/hierarchy.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index dd4341127..f2f0d6e5b 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -174,6 +174,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check cell->type = cell->type.str().substr(pos_type + 1); } dict interfaces_to_add_to_submodule; + dict modports_used_in_submodule; if (design->modules_.count(cell->type) == 0) { @@ -224,6 +225,14 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check // some lists, so that they can be replaced further down: for (auto &conn : cell->connections()) { if(mod->wires_.count(conn.first) != 0 && mod->wire(conn.first)->get_bool_attribute("\\is_interface")) { // Check if the connection is present as an interface in the sub-module's port list + //const pool &interface_type_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_type"); + //for (auto &d : interface_type_pool) { // TODO: Compare interface type to type in parent module + //} + const pool &interface_modport_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_modport"); + std::string interface_modport = ""; + for (auto &d : interface_modport_pool) { + interface_modport = "\\" + d; + } if(conn.second.bits().size() == 1 && conn.second.bits()[0].wire->get_bool_attribute("\\is_interface")) { std::string interface_name_str = conn.second.bits()[0].wire->name.str(); interface_name_str.replace(0,23,""); @@ -247,6 +256,9 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check } connections_to_remove.push_back(conn.first); interfaces_to_add_to_submodule[conn.first] = interfaces_in_module.at(interface_name); + if (interface_modport != "") { + modports_used_in_submodule[conn.first] = interface_modport; + } } else will_do_step = true; } @@ -322,7 +334,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check continue; } - cell->type = mod->derive(design, cell->parameters, interfaces_to_add_to_submodule); + cell->type = mod->derive(design, cell->parameters, interfaces_to_add_to_submodule, modports_used_in_submodule); cell->parameters.clear(); did_something = true; -- cgit v1.2.3 From c50afc4246d552db079aec303b0d79ae92107a67 Mon Sep 17 00:00:00 2001 From: Ruben Undheim Date: Sat, 13 Oct 2018 20:34:44 +0200 Subject: Documentation improvements etc. - Mention new feature in the SystemVerilog section in the README file - Commented changes much better - Rename a few signals to make it clearer - Prevent warning for unused signals in an easier way - Add myself as copyright holder to 2 files - Fix one potential memory leak (delete 'wire' if not in modport) --- passes/hierarchy/hierarchy.cc | 65 +++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 27 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index f2f0d6e5b..7e93a6f9a 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -2,6 +2,7 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2018 Ruben Undheim * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -145,6 +146,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check std::map> array_cells; std::string filename; + // Always keep track of all derived interfaces available in the current module in 'interfaces_in_module': dict interfaces_in_module; for (auto &cell_it : module->cells_) { @@ -222,50 +224,54 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check RTLIL::Module *mod = design->module(cell->type); // Go over all connections and see if any of them are SV interfaces. If they are, then add the replacements to - // some lists, so that they can be replaced further down: + // some lists, so that the ports for sub-modules can be replaced further down: for (auto &conn : cell->connections()) { if(mod->wires_.count(conn.first) != 0 && mod->wire(conn.first)->get_bool_attribute("\\is_interface")) { // Check if the connection is present as an interface in the sub-module's port list //const pool &interface_type_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_type"); - //for (auto &d : interface_type_pool) { // TODO: Compare interface type to type in parent module + //for (auto &d : interface_type_pool) { // TODO: Compare interface type to type in parent module (not crucially important, but good for robustness) //} + + // Find if the sub-module has set a modport for the current interface connection: const pool &interface_modport_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_modport"); std::string interface_modport = ""; for (auto &d : interface_modport_pool) { interface_modport = "\\" + d; } - if(conn.second.bits().size() == 1 && conn.second.bits()[0].wire->get_bool_attribute("\\is_interface")) { + if(conn.second.bits().size() == 1 && conn.second.bits()[0].wire->get_bool_attribute("\\is_interface")) { // Check if the connected wire is a potential interface in the parent module std::string interface_name_str = conn.second.bits()[0].wire->name.str(); - interface_name_str.replace(0,23,""); + interface_name_str.replace(0,23,""); // Strip the prefix '$dummywireforinterface' from the dummy wire to get the name interface_name_str = "\\" + interface_name_str; RTLIL::IdString interface_name = interface_name_str; - bool will_do_step = false; - if(module->get_bool_attribute("\\interfaces_replaced_in_module")) { + bool not_found_interface = false; + if(module->get_bool_attribute("\\interfaces_replaced_in_module")) { // If 'interfaces' in the cell have not be been handled yet, there is no need to derive the sub-module either if (interfaces_in_module.count(interface_name) > 0) { // Check if the interface instance is present in module RTLIL::Module *mod_replace_ports = interfaces_in_module.at(interface_name); - for (auto &mod_wire : mod_replace_ports->wires_) { - std::string signal_name1 = conn.first.str() + "." + log_id(mod_wire.first); - std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire.first); - connections_to_add_name.push_back(RTLIL::IdString(signal_name1)); - if(module->wires_.count(signal_name2) == 0) { - log_error("Could not find signal '%s' in '%s'\n", signal_name2.c_str(), log_id(module->name)); + for (auto &mod_wire : mod_replace_ports->wires_) { // Go over all wires in interface, and add replacements to lists. + std::string signal_name1 = conn.first.str() + "." + log_id(mod_wire.first); + std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire.first); + connections_to_add_name.push_back(RTLIL::IdString(signal_name1)); + if(module->wires_.count(signal_name2) == 0) { + log_error("Could not find signal '%s' in '%s'\n", signal_name2.c_str(), log_id(module->name)); + } + else { + RTLIL::Wire *wire_in_parent = module->wire(signal_name2); + connections_to_add_signal.push_back(wire_in_parent); + } } - else { - RTLIL::Wire *wire_in_parent = module->wire(signal_name2); - connections_to_add_signal.push_back(wire_in_parent); + connections_to_remove.push_back(conn.first); + interfaces_to_add_to_submodule[conn.first] = interfaces_in_module.at(interface_name); + + // Add modports to a dict which will be passed to AstModule::derive + if (interface_modport != "") { + modports_used_in_submodule[conn.first] = interface_modport; } } - connections_to_remove.push_back(conn.first); - interfaces_to_add_to_submodule[conn.first] = interfaces_in_module.at(interface_name); - if (interface_modport != "") { - modports_used_in_submodule[conn.first] = interface_modport; - } - } - else will_do_step = true; + else not_found_interface = true; } - else will_do_step = true; + else not_found_interface = true; // If the interface instance has not already been derived in the module, we cannot complete at this stage. Set "has_interfaces_not_found" // which will delay the expansion of this cell: - if (will_do_step) { + if (not_found_interface) { // If we have already gone over all cells in this module, and the interface has still not been found - flag it as an error: if(!(module->get_bool_attribute("\\cells_not_processed"))) { log_warning("Could not find interface instance for `%s' in `%s'\n", log_id(interface_name), log_id(module)); @@ -348,13 +354,16 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check interfaces_in_module[cell->name] = derived_module; did_something = true; } - // We unset 'module_not_derived' such that we will not rederive the cell again (needed when there are interfaces connected to the cell) + // We clear 'module_not_derived' such that we will not rederive the cell again (needed when there are interfaces connected to the cell) cell->attributes.erase("\\module_not_derived"); } - // Setting a flag such that it can be known that we have been through all cells at least once, such that we can know whether to flag - // an error because of interface instances not found: + // Clear the attribute 'cells_not_processed' such that it can be known that we + // have been through all cells at least once, and that we can know whether + // to flag an error because of interface instances not found: module->attributes.erase("\\cells_not_processed"); + + // If any interface instances were found in the module, we need to rederive it completely: if (interfaces_in_module.size() > 0 && !module->get_bool_attribute("\\interfaces_replaced_in_module")) { module->reprocess_module(design, interfaces_in_module); return did_something; @@ -736,6 +745,7 @@ struct HierarchyPass : public Pass { } + // The top module might have changed if interface instances have been detected in it: RTLIL::Module *tmp_top_mod = check_if_top_has_changed(design, top_mod); if (tmp_top_mod != NULL) { if (tmp_top_mod != top_mod){ @@ -744,6 +754,7 @@ struct HierarchyPass : public Pass { } } + // Delete modules marked as 'to_delete': std::vector modules_to_delete; for(auto &mod_it : design->modules_) { if (mod_it.second->get_bool_attribute("\\to_delete")) { -- cgit v1.2.3 From 397dfccb304a12a40d34c4454a5cb4acee8be75f Mon Sep 17 00:00:00 2001 From: Ruben Undheim Date: Sat, 20 Oct 2018 11:58:25 +0200 Subject: Support for SystemVerilog interfaces as a port in the top level module + test case --- passes/hierarchy/hierarchy.cc | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 7e93a6f9a..9c7dad3d3 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -146,6 +146,17 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check std::map> array_cells; std::string filename; + bool has_interface_ports = false; + + // If any of the ports are actually interface ports, we will always need to + // reprocess the module: + if(!module->get_bool_attribute("\\interfaces_replaced_in_module")) { + for (auto &wire : module->wires_) { + if ((wire.second->port_input || wire.second->port_output) && wire.second->get_bool_attribute("\\is_interface")) + has_interface_ports = true; + } + } + // Always keep track of all derived interfaces available in the current module in 'interfaces_in_module': dict interfaces_in_module; for (auto &cell_it : module->cells_) @@ -244,8 +255,14 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check RTLIL::IdString interface_name = interface_name_str; bool not_found_interface = false; if(module->get_bool_attribute("\\interfaces_replaced_in_module")) { // If 'interfaces' in the cell have not be been handled yet, there is no need to derive the sub-module either - if (interfaces_in_module.count(interface_name) > 0) { // Check if the interface instance is present in module - RTLIL::Module *mod_replace_ports = interfaces_in_module.at(interface_name); + int nexactmatch = interfaces_in_module.count(interface_name) > 0; + std::string interface_name_str2 = interface_name_str + "_inst_from_top_dummy"; + RTLIL::IdString interface_name2 = interface_name_str2; + int nmatch2 = interfaces_in_module.count(interface_name2) > 0; + if (nexactmatch > 0 || nmatch2 > 0) { // Check if the interface instance is present in module + if (nexactmatch != 0) + interface_name2 = interface_name; + RTLIL::Module *mod_replace_ports = interfaces_in_module.at(interface_name2); for (auto &mod_wire : mod_replace_ports->wires_) { // Go over all wires in interface, and add replacements to lists. std::string signal_name1 = conn.first.str() + "." + log_id(mod_wire.first); std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire.first); @@ -259,7 +276,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check } } connections_to_remove.push_back(conn.first); - interfaces_to_add_to_submodule[conn.first] = interfaces_in_module.at(interface_name); + interfaces_to_add_to_submodule[conn.first] = interfaces_in_module.at(interface_name2); // Add modports to a dict which will be passed to AstModule::derive if (interface_modport != "") { @@ -363,8 +380,8 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check module->attributes.erase("\\cells_not_processed"); - // If any interface instances were found in the module, we need to rederive it completely: - if (interfaces_in_module.size() > 0 && !module->get_bool_attribute("\\interfaces_replaced_in_module")) { + // If any interface instances or interface ports were found in the module, we need to rederive it completely: + if ((interfaces_in_module.size() > 0 || has_interface_ports) && !module->get_bool_attribute("\\interfaces_replaced_in_module")) { module->reprocess_module(design, interfaces_in_module); return did_something; } @@ -438,6 +455,20 @@ void hierarchy_clean(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib) for (auto &it : design->modules_) if (used.count(it.second) == 0) del_modules.push_back(it.second); + else { + // Now all interface ports must have been exploded, and it is hence + // safe to delete all of the remaining dummy interface ports: + pool del_wires; + for(auto &wire : it.second->wires_) { + if ((wire.second->port_input || wire.second->port_output) && wire.second->get_bool_attribute("\\is_interface")) { + del_wires.insert(wire.second); + } + } + if (del_wires.size() > 0) { + it.second->remove(del_wires); + it.second->fixup_ports(); + } + } int del_counter = 0; for (auto mod : del_modules) { -- cgit v1.2.3 From 436e3c0a7cbe5a482e14857e4e5a1d02b3464ae8 Mon Sep 17 00:00:00 2001 From: Ruben Undheim Date: Sat, 20 Oct 2018 12:45:51 +0200 Subject: Refactor code to avoid code duplication + added comments --- passes/hierarchy/hierarchy.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 9c7dad3d3..0c782b8ab 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -255,12 +255,15 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check RTLIL::IdString interface_name = interface_name_str; bool not_found_interface = false; if(module->get_bool_attribute("\\interfaces_replaced_in_module")) { // If 'interfaces' in the cell have not be been handled yet, there is no need to derive the sub-module either + // Check if the interface instance is present in module: + // Interface instances may either have the plain name or the name appended with '_inst_from_top_dummy'. + // Check for both of them here int nexactmatch = interfaces_in_module.count(interface_name) > 0; std::string interface_name_str2 = interface_name_str + "_inst_from_top_dummy"; RTLIL::IdString interface_name2 = interface_name_str2; int nmatch2 = interfaces_in_module.count(interface_name2) > 0; - if (nexactmatch > 0 || nmatch2 > 0) { // Check if the interface instance is present in module - if (nexactmatch != 0) + if (nexactmatch > 0 || nmatch2 > 0) { + if (nexactmatch != 0) // Choose the one with the plain name if it exists interface_name2 = interface_name; RTLIL::Module *mod_replace_ports = interfaces_in_module.at(interface_name2); for (auto &mod_wire : mod_replace_ports->wires_) { // Go over all wires in interface, and add replacements to lists. -- cgit v1.2.3 From efa278e232d20ea080743801bd91d55ec62955cf Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 7 Dec 2018 19:14:07 +0000 Subject: Fix typographical and grammatical errors and inconsistencies. The initial list of hits was generated with the codespell command below, and each hit was evaluated and fixed manually while taking context into consideration. DIRS="kernel/ frontends/ backends/ passes/ techlibs/" DIRS="${DIRS} libs/ezsat/ libs/subcircuit" codespell $DIRS -S *.o -L upto,iff,thru,synopsys,uint More hits were found by looking through comments and strings manually. --- passes/hierarchy/hierarchy.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 0c782b8ab..0e28dbca2 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -543,7 +543,7 @@ struct HierarchyPass : public Pass { log(" an unknown module is used as cell type.\n"); log("\n"); log(" -simcheck\n"); - log(" like -check, but also thow an error if blackbox modules are\n"); + log(" like -check, but also throw an error if blackbox modules are\n"); log(" instantiated, and throw an error if the design has no top module\n"); log("\n"); log(" -purge_lib\n"); -- cgit v1.2.3 From 5c504c5ae676488f7e0b53f827f189fa7cacb2c8 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Fri, 15 Feb 2019 11:31:37 -0800 Subject: Define basic_cell_type() function and use it to derive the cell type for array references (instead of duplicating the code). --- passes/hierarchy/hierarchy.cc | 50 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 10 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 0e28dbca2..332ebdfbb 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -140,6 +140,23 @@ void generate(RTLIL::Design *design, const std::vector &celltypes, } } +// Return the "basic" type for an array item. +std::string basic_cell_type(const std::string celltype, int pos[3] = nullptr) { + std::string basicType = celltype; + if (celltype.substr(0, 7) == "$array:") { + int pos_idx = celltype.find_first_of(':'); + int pos_num = celltype.find_first_of(':', pos_idx + 1); + int pos_type = celltype.find_first_of(':', pos_num + 1); + basicType = celltype.substr(pos_type + 1); + if (pos != nullptr) { + pos[0] = pos_idx; + pos[1] = pos_num; + pos[2] = pos_type; + } + } + return basicType; +} + bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, bool flag_simcheck, std::vector &libdirs) { bool did_something = false; @@ -178,9 +195,11 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check std::vector connections_to_add_signal; if (cell->type.substr(0, 7) == "$array:") { - int pos_idx = cell->type.str().find_first_of(':'); - int pos_num = cell->type.str().find_first_of(':', pos_idx + 1); - int pos_type = cell->type.str().find_first_of(':', pos_num + 1); + int pos[3]; + basic_cell_type(cell->type.str(), pos); + int pos_idx = pos[0]; + int pos_num = pos[1]; + int pos_type = pos[2]; int idx = atoi(cell->type.str().substr(pos_idx + 1, pos_num).c_str()); int num = atoi(cell->type.str().substr(pos_num + 1, pos_type).c_str()); array_cells[cell] = std::pair(idx, num); @@ -439,10 +458,7 @@ void hierarchy_worker(RTLIL::Design *design, std::setcells()) { std::string celltype = cell->type.str(); if (celltype.substr(0, 7) == "$array:") { - int pos_idx = celltype.find_first_of(':'); - int pos_num = celltype.find_first_of(':', pos_idx + 1); - int pos_type = celltype.find_first_of(':', pos_num + 1); - celltype = celltype.substr(pos_type + 1); + celltype = basic_cell_type(celltype); } if (design->module(celltype)) hierarchy_worker(design, used, design->module(celltype), indent+4); @@ -502,9 +518,23 @@ int find_top_mod_score(Design *design, Module *module, dict &db) if (db.count(module) == 0) { int score = 0; db[module] = 0; - for (auto cell : module->cells()) - if (design->module(cell->type)) - score = max(score, find_top_mod_score(design, design->module(cell->type), db) + 1); + for (auto cell : module->cells()) { + std::string celltype = cell->type.str(); + // Is this an array instance + if (celltype.substr(0, 7) == "$array:") { + celltype = basic_cell_type(celltype); + // Is this cell is a module instance? + if (celltype[0] != '$') { + auto instModule = design->module(celltype); + // If there is no instance for this, issue a warning. + if (instModule == NULL) { + log_warning("find_top_mod_score: no instance for %s.%s\n", celltype.c_str(), cell->name.c_str()); + } + if (instModule != NULL) + score = max(score, find_top_mod_score(design, instModule, db) + 1); + } + } + } db[module] = score; } return db.at(module); -- cgit v1.2.3 From 5c4a72c43ef61420b4b099d87949b0fdba0f4b55 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Tue, 19 Feb 2019 14:35:15 -0800 Subject: Fix normal (non-array) hierarchy -auto-top. Add simple test. --- passes/hierarchy/hierarchy.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 332ebdfbb..f112e969e 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -523,15 +523,15 @@ int find_top_mod_score(Design *design, Module *module, dict &db) // Is this an array instance if (celltype.substr(0, 7) == "$array:") { celltype = basic_cell_type(celltype); - // Is this cell is a module instance? - if (celltype[0] != '$') { - auto instModule = design->module(celltype); - // If there is no instance for this, issue a warning. - if (instModule == NULL) { - log_warning("find_top_mod_score: no instance for %s.%s\n", celltype.c_str(), cell->name.c_str()); - } - if (instModule != NULL) - score = max(score, find_top_mod_score(design, instModule, db) + 1); + } + // Is this cell a module instance? + if (celltype[0] != '$') { + auto instModule = design->module(celltype); + // If there is no instance for this, issue a warning. + if (instModule == NULL) { + log_warning("find_top_mod_score: no instance for %s.%s\n", celltype.c_str(), cell->name.c_str()); + } else { + score = max(score, find_top_mod_score(design, instModule, db) + 1); } } } -- cgit v1.2.3 From 71bcc4c644b0dafa760ff8b6d7bd1109836be621 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Fri, 22 Feb 2019 16:06:10 -0800 Subject: Address requested changes - don't require non-$ name. Suppress warning if name does begin with a `$`. Fix hierachy tests so they have something to grep. Announce hierarchy test types. --- passes/hierarchy/hierarchy.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index f112e969e..cb54ffa58 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -525,14 +525,14 @@ int find_top_mod_score(Design *design, Module *module, dict &db) celltype = basic_cell_type(celltype); } // Is this cell a module instance? - if (celltype[0] != '$') { - auto instModule = design->module(celltype); - // If there is no instance for this, issue a warning. - if (instModule == NULL) { + auto instModule = design->module(celltype); + // If there is no instance for this, issue a warning. + if (instModule == NULL) { + // but only if we're sure it is a reference to a module. + if (celltype[0] != '$') log_warning("find_top_mod_score: no instance for %s.%s\n", celltype.c_str(), cell->name.c_str()); - } else { - score = max(score, find_top_mod_score(design, instModule, db) + 1); - } + } else { + score = max(score, find_top_mod_score(design, instModule, db) + 1); } } db[module] = score; -- cgit v1.2.3 From c258b99040c8414952a3aceae874dc47563540dc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 24 Feb 2019 20:41:36 +0100 Subject: Minor changes ontop of 71bcc4c: Remove hierarchy warning that is redundant to -check Signed-off-by: Clifford Wolf --- passes/hierarchy/hierarchy.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index cb54ffa58..2d8edebb5 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -527,11 +527,7 @@ int find_top_mod_score(Design *design, Module *module, dict &db) // Is this cell a module instance? auto instModule = design->module(celltype); // If there is no instance for this, issue a warning. - if (instModule == NULL) { - // but only if we're sure it is a reference to a module. - if (celltype[0] != '$') - log_warning("find_top_mod_score: no instance for %s.%s\n", celltype.c_str(), cell->name.c_str()); - } else { + if (instModule != nullptr) { score = max(score, find_top_mod_score(design, instModule, db) + 1); } } -- cgit v1.2.3 From ae9286386de117991f887f919f5af3fac40173cc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Mar 2019 12:36:46 -0800 Subject: Only run derive on blackbox modules when ports have dynamic size Signed-off-by: Clifford Wolf --- passes/hierarchy/hierarchy.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 2d8edebb5..88c339e8c 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -910,7 +910,7 @@ struct HierarchyPass : public Pass { if (m == nullptr) continue; - if (m->get_bool_attribute("\\blackbox") && !cell->parameters.empty()) { + if (m->get_bool_attribute("\\blackbox") && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) { IdString new_m_name = m->derive(design, cell->parameters, true); if (new_m_name.empty()) continue; -- cgit v1.2.3 From f4abc21d8ad79621cc24852bd76abf40a9d9f702 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 18 Apr 2019 17:42:12 +0200 Subject: Add "whitebox" attribute, add "read_verilog -wb" Signed-off-by: Clifford Wolf --- passes/hierarchy/hierarchy.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 88c339e8c..b8ff99884 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -346,9 +346,9 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check } RTLIL::Module *mod = design->modules_[cell->type]; - if (design->modules_.at(cell->type)->get_bool_attribute("\\blackbox")) { + if (design->modules_.at(cell->type)->get_blackbox_attribute()) { if (flag_simcheck) - log_error("Module `%s' referenced in module `%s' in cell `%s' is a blackbox module.\n", + log_error("Module `%s' referenced in module `%s' in cell `%s' is a blackbox/whitebox module.\n", cell->type.c_str(), module->name.c_str(), cell->name.c_str()); continue; } @@ -451,7 +451,7 @@ void hierarchy_worker(RTLIL::Design *design, std::setname.c_str()); - else if (!mod->get_bool_attribute("\\blackbox")) + else if (!mod->get_blackbox_attribute()) log("Used module: %*s%s\n", indent, "", mod->name.c_str()); used.insert(mod); @@ -491,7 +491,7 @@ void hierarchy_clean(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib) int del_counter = 0; for (auto mod : del_modules) { - if (!purge_lib && mod->get_bool_attribute("\\blackbox")) + if (!purge_lib && mod->get_blackbox_attribute()) continue; log("Removing unused module `%s'.\n", mod->name.c_str()); design->modules_.erase(mod->name); @@ -910,7 +910,7 @@ struct HierarchyPass : public Pass { if (m == nullptr) continue; - if (m->get_bool_attribute("\\blackbox") && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) { + if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) { IdString new_m_name = m->derive(design, cell->parameters, true); if (new_m_name.empty()) continue; -- cgit v1.2.3 From a27b42e97571c817b0698964329d61dddc6e9a3a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 13 Mar 2019 19:42:18 +0000 Subject: WIP -chparam support for hierarchy when verific --- passes/hierarchy/hierarchy.cc | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index b8ff99884..483b386e5 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -570,7 +570,7 @@ struct HierarchyPass : public Pass { log("\n"); log(" -simcheck\n"); log(" like -check, but also throw an error if blackbox modules are\n"); - log(" instantiated, and throw an error if the design has no top module\n"); + log(" instantiated, and throw an error if the design has no top module.\n"); log("\n"); log(" -purge_lib\n"); log(" by default the hierarchy command will not remove library (blackbox)\n"); @@ -583,20 +583,20 @@ struct HierarchyPass : public Pass { log("\n"); log(" -keep_positionals\n"); log(" per default this pass also converts positional arguments in cells\n"); - log(" to arguments using port names. this option disables this behavior.\n"); + log(" to arguments using port names. This option disables this behavior.\n"); log("\n"); log(" -keep_portwidths\n"); log(" per default this pass adjusts the port width on cells that are\n"); - log(" module instances when the width does not match the module port. this\n"); + log(" module instances when the width does not match the module port. This\n"); log(" option disables this behavior.\n"); log("\n"); log(" -nokeep_asserts\n"); log(" per default this pass sets the \"keep\" attribute on all modules\n"); - log(" that directly or indirectly contain one or more $assert cells. this\n"); + log(" that directly or indirectly contain one or more $assert cells. This\n"); log(" option disables this behavior.\n"); log("\n"); log(" -top \n"); - log(" use the specified top module to built a design hierarchy. modules\n"); + log(" use the specified top module to build the design hierarchy. Modules\n"); log(" outside this tree (unused modules) are removed.\n"); log("\n"); log(" when the -top option is used, the 'top' attribute will be set on the\n"); @@ -606,6 +606,12 @@ struct HierarchyPass : public Pass { log(" -auto-top\n"); log(" automatically determine the top of the design hierarchy and mark it.\n"); log("\n"); + log(" -chparam name value \n"); + log(" elaborate the top module using this parameter value. Modules on which\n"); + log(" this parameter does not exist may cause a warning message to be output.\n"); + log(" This option can be specified multiple times to override multiple\n"); + log(" parameters. String values must be passed in double quotes (\").\n"); + log("\n"); log("In -generate mode this pass generates blackbox modules for the given cell\n"); log("types (wildcards supported). For this the design is searched for cells that\n"); log("match the given types and then the given port declarations are used to\n"); @@ -641,6 +647,7 @@ struct HierarchyPass : public Pass { bool nokeep_asserts = false; std::vector generate_cells; std::vector generate_ports; + std::map parameters; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -729,6 +736,16 @@ struct HierarchyPass : public Pass { auto_top_mode = true; continue; } + if (args[argidx] == "-chparam" && argidx+2 < args.size()) { + const std::string &key = args[++argidx]; + const std::string &value = args[++argidx]; + auto r = parameters.emplace(key, value); + if (!r.second) { + log_warning_noprefix("-chparam %s already specified: overwriting.\n", key.c_str()); + r.first->second = value; + } + continue; + } break; } extra_args(args, argidx, design, false); @@ -736,7 +753,7 @@ struct HierarchyPass : public Pass { if (!load_top_mod.empty()) { #ifdef YOSYS_ENABLE_VERIFIC if (verific_import_pending) { - verific_import(design, load_top_mod); + verific_import(design, parameters, load_top_mod); top_mod = design->module(RTLIL::escape_id(load_top_mod)); } #endif @@ -745,7 +762,7 @@ struct HierarchyPass : public Pass { } else { #ifdef YOSYS_ENABLE_VERIFIC if (verific_import_pending) - verific_import(design); + verific_import(design, parameters); #endif } -- cgit v1.2.3 From eb21bf36513151a6df434cf277be0df70337356a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 14 Mar 2019 15:29:43 +0000 Subject: log_warning_noprefix -> log_warning as per review --- passes/hierarchy/hierarchy.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 483b386e5..71dcfb194 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -741,7 +741,7 @@ struct HierarchyPass : public Pass { const std::string &value = args[++argidx]; auto r = parameters.emplace(key, value); if (!r.second) { - log_warning_noprefix("-chparam %s already specified: overwriting.\n", key.c_str()); + log_warning("-chparam %s already specified: overwriting.\n", key.c_str()); r.first->second = value; } continue; -- cgit v1.2.3 From ec39cfd0ad8c0d3d5757c7a8736952e74dd6dd79 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 3 May 2019 22:03:43 +0200 Subject: Add "hierarchy -chparam" support for non-verific top modules Signed-off-by: Clifford Wolf --- passes/hierarchy/hierarchy.cc | 47 ++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 12 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 71dcfb194..72bc2e133 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -592,8 +592,8 @@ struct HierarchyPass : public Pass { log("\n"); log(" -nokeep_asserts\n"); log(" per default this pass sets the \"keep\" attribute on all modules\n"); - log(" that directly or indirectly contain one or more $assert cells. This\n"); - log(" option disables this behavior.\n"); + log(" that directly or indirectly contain one or more formal properties.\n"); + log(" This option disables this behavior.\n"); log("\n"); log(" -top \n"); log(" use the specified top module to build the design hierarchy. Modules\n"); @@ -722,14 +722,7 @@ struct HierarchyPass : public Pass { if (args[argidx] == "-top") { if (++argidx >= args.size()) log_cmd_error("Option -top requires an additional argument!\n"); - top_mod = design->modules_.count(RTLIL::escape_id(args[argidx])) ? design->modules_.at(RTLIL::escape_id(args[argidx])) : NULL; - if (top_mod == NULL && design->modules_.count("$abstract" + RTLIL::escape_id(args[argidx]))) { - dict empty_parameters; - design->modules_.at("$abstract" + RTLIL::escape_id(args[argidx]))->derive(design, empty_parameters); - top_mod = design->modules_.count(RTLIL::escape_id(args[argidx])) ? design->modules_.at(RTLIL::escape_id(args[argidx])) : NULL; - } - if (top_mod == NULL) - load_top_mod = args[argidx]; + load_top_mod = args[argidx]; continue; } if (args[argidx] == "-auto-top") { @@ -750,7 +743,37 @@ struct HierarchyPass : public Pass { } extra_args(args, argidx, design, false); - if (!load_top_mod.empty()) { + if (!load_top_mod.empty()) + { + IdString top_name = RTLIL::escape_id(load_top_mod); + IdString abstract_id = "$abstract" + RTLIL::escape_id(load_top_mod); + top_mod = design->module(top_name); + + dict top_parameters; + for (auto ¶ : parameters) { + SigSpec sig_value; + if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second)) + log_cmd_error("Can't decode value '%s'!\n", para.second.c_str()); + top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const(); + } + + if (top_mod == nullptr && design->module(abstract_id)) + top_mod = design->module(design->module(abstract_id)->derive(design, top_parameters)); + else if (top_mod != nullptr && !top_parameters.empty()) + top_mod = design->module(top_mod->derive(design, top_parameters)); + + if (top_mod != nullptr && top_mod->name != top_name) { + Module *m = top_mod->clone(); + m->name = top_name; + Module *old_mod = design->module(top_name); + if (old_mod) + design->remove(old_mod); + design->add(m); + top_mod = m; + } + } + + if (top_mod == nullptr && !load_top_mod.empty()) { #ifdef YOSYS_ENABLE_VERIFIC if (verific_import_pending) { verific_import(design, parameters, load_top_mod); @@ -863,7 +886,7 @@ struct HierarchyPass : public Pass { std::map cache; for (auto mod : design->modules()) if (set_keep_assert(cache, mod)) { - log("Module %s directly or indirectly contains $assert cells -> setting \"keep\" attribute.\n", log_id(mod)); + log("Module %s directly or indirectly contains formal properties -> setting \"keep\" attribute.\n", log_id(mod)); mod->set_bool_attribute("\\keep"); } } -- cgit v1.2.3 From ed625a3102233bf9c9af17e56575dc4a0ed8946c Mon Sep 17 00:00:00 2001 From: Stefan Biereigel Date: Mon, 27 May 2019 18:00:22 +0200 Subject: move wand/wor resolution into hierarchy pass --- passes/hierarchy/hierarchy.cc | 78 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 72bc2e133..013923816 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -562,7 +562,7 @@ struct HierarchyPass : public Pass { log("In parametric designs, a module might exists in several variations with\n"); log("different parameter values. This pass looks at all modules in the current\n"); log("design an re-runs the language frontends for the parametric modules as\n"); - log("needed.\n"); + log("needed. It also resolves assignments to wired logic data types (wand/wor).\n"); log("\n"); log(" -check\n"); log(" also check the design hierarchy. this generates an error when\n"); @@ -941,6 +941,61 @@ struct HierarchyPass : public Pass { std::set blackbox_derivatives; std::vector design_modules = design->modules(); + std::map wlogic_map; + + for (auto module : design_modules) + for (auto wire : module->wires()) + { + Cell *reduce = nullptr; + if (wire->get_bool_attribute("\\wand")) { + reduce = module->addCell( + stringf("$%s_reduce", wire->name.c_str()), "$reduce_and"); + } + if (wire->get_bool_attribute("\\wor")) { + reduce = module->addCell( + stringf("$%s_reduce", wire->name.c_str()), "$reduce_or"); + } + if (reduce) { + if (wire->width > 1) + log_error("Multi-bit wand/wor unsupported (%s)\n", + log_id(wire)); + + reduce->parameters["\\A_SIGNED"] = Const(0); + reduce->parameters["\\A_WIDTH"] = Const(0); + reduce->setPort("\\A", SigSpec()); + + reduce->parameters["\\Y_WIDTH"] = Const(1); + reduce->setPort("\\Y", wire); + wlogic_map[wire] = reduce; + } + } + + for (auto module : design_modules) { + std::vector new_connections; + for (auto &conn : module->connections()) + { + SigSpec sig = conn.first; + for (int i = 0; i < GetSize(sig); i++) { + Wire *sigwire = sig[i].wire; + if (sigwire == nullptr) + continue; + + if (sigwire->get_bool_attribute("\\wor") || sigwire->get_bool_attribute("\\wand")) { + Cell *reduce = wlogic_map[sigwire]; + SigSpec reduce_in = reduce->getPort("\\A"); + int reduce_width = reduce->getParam("\\A_WIDTH").as_int(); + Wire *new_reduce_input = module->addWire( + stringf("%s_in%d", reduce->name.c_str(), reduce_width)); + reduce_in.append(new_reduce_input); + reduce->setPort("\\A", reduce_in); + reduce->fixup_parameters(); + sig[i] = new_reduce_input; + } + } + new_connections.push_back(SigSig(sig, conn.second)); + } + module->new_connections(new_connections); + } for (auto module : design_modules) for (auto cell : module->cells()) @@ -996,6 +1051,27 @@ struct HierarchyPass : public Pass { cell->setPort(conn.first, sig); } + for (int i = 0; i < GetSize(sig); i++) { + Wire *sigwire = sig[i].wire; + if (sigwire == nullptr) + continue; + + if (sigwire->get_bool_attribute("\\wor") || sigwire->get_bool_attribute("\\wand")) { + if (w->port_output && !w->port_input) { + Cell *reduce = wlogic_map[sigwire]; + SigSpec reduce_in = reduce->getPort("\\A"); + int reduce_width = reduce->getParam("\\A_WIDTH").as_int(); + Wire *new_reduce_input = module->addWire( + stringf("$%s_in%d", reduce->name.c_str(), reduce_width)); + reduce_in.append(new_reduce_input); + reduce->setPort("\\A", reduce_in); + reduce->fixup_parameters(); + sig[i] = new_reduce_input; + } + } + } + cell->setPort(conn.first, sig); + if (w->port_output && !w->port_input && sig.has_const()) log_error("Output port %s.%s.%s (%s) is connected to constants: %s\n", log_id(module), log_id(cell), log_id(conn.first), log_id(cell->type), log_signal(sig)); -- cgit v1.2.3 From ba2185ead89fdb6afeec6043ab18f2e045d80247 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 28 May 2019 16:43:25 +0200 Subject: Refactor hierarchy wand/wor handling Signed-off-by: Clifford Wolf --- passes/hierarchy/hierarchy.cc | 245 ++++++++++++++++++++++++------------------ 1 file changed, 143 insertions(+), 102 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 013923816..24e64a9b2 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -562,7 +562,8 @@ struct HierarchyPass : public Pass { log("In parametric designs, a module might exists in several variations with\n"); log("different parameter values. This pass looks at all modules in the current\n"); log("design an re-runs the language frontends for the parametric modules as\n"); - log("needed. It also resolves assignments to wired logic data types (wand/wor).\n"); + log("needed. It also resolves assignments to wired logic data types (wand/wor),\n"); + log("resolves positional module parameters, unroll array instances, and more.\n"); log("\n"); log(" -check\n"); log(" also check the design hierarchy. this generates an error when\n"); @@ -941,140 +942,180 @@ struct HierarchyPass : public Pass { std::set blackbox_derivatives; std::vector design_modules = design->modules(); - std::map wlogic_map; for (auto module : design_modules) - for (auto wire : module->wires()) { - Cell *reduce = nullptr; - if (wire->get_bool_attribute("\\wand")) { - reduce = module->addCell( - stringf("$%s_reduce", wire->name.c_str()), "$reduce_and"); - } - if (wire->get_bool_attribute("\\wor")) { - reduce = module->addCell( - stringf("$%s_reduce", wire->name.c_str()), "$reduce_or"); - } - if (reduce) { - if (wire->width > 1) - log_error("Multi-bit wand/wor unsupported (%s)\n", - log_id(wire)); - - reduce->parameters["\\A_SIGNED"] = Const(0); - reduce->parameters["\\A_WIDTH"] = Const(0); - reduce->setPort("\\A", SigSpec()); - - reduce->parameters["\\Y_WIDTH"] = Const(1); - reduce->setPort("\\Y", wire); - wlogic_map[wire] = reduce; + pool wand_wor_index; + dict wand_map, wor_map; + vector new_connections; + + for (auto wire : module->wires()) + { + if (wire->get_bool_attribute("\\wand")) { + wand_map[wire] = SigSpec(); + wand_wor_index.insert(wire); + } + if (wire->get_bool_attribute("\\wor")) { + wor_map[wire] = SigSpec(); + wand_wor_index.insert(wire); + } } - } - for (auto module : design_modules) { - std::vector new_connections; for (auto &conn : module->connections()) { - SigSpec sig = conn.first; - for (int i = 0; i < GetSize(sig); i++) { - Wire *sigwire = sig[i].wire; - if (sigwire == nullptr) - continue; + SigSig new_conn; + int cursor = 0; - if (sigwire->get_bool_attribute("\\wor") || sigwire->get_bool_attribute("\\wand")) { - Cell *reduce = wlogic_map[sigwire]; - SigSpec reduce_in = reduce->getPort("\\A"); - int reduce_width = reduce->getParam("\\A_WIDTH").as_int(); - Wire *new_reduce_input = module->addWire( - stringf("%s_in%d", reduce->name.c_str(), reduce_width)); - reduce_in.append(new_reduce_input); - reduce->setPort("\\A", reduce_in); - reduce->fixup_parameters(); - sig[i] = new_reduce_input; + for (auto c : conn.first.chunks()) + { + Wire *w = c.wire; + SigSpec rhs = conn.second.extract(cursor, GetSize(c)); + + if (wand_wor_index.count(w) == 0) { + new_conn.first.append(c); + new_conn.second.append(rhs); + } else { + if (wand_map.count(w)) { + SigSpec sig = SigSpec(State::S1, GetSize(w)); + sig.replace(c.offset, rhs); + wand_map.at(w).append(sig); + } else { + SigSpec sig = SigSpec(State::S0, GetSize(w)); + sig.replace(c.offset, rhs); + wor_map.at(w).append(sig); + } } + cursor += GetSize(c); } - new_connections.push_back(SigSig(sig, conn.second)); + new_connections.push_back(new_conn); } module->new_connections(new_connections); - } - for (auto module : design_modules) - for (auto cell : module->cells()) - { - Module *m = design->module(cell->type); + for (auto cell : module->cells()) + { + if (!cell->known()) + continue; - if (m == nullptr) - continue; + for (auto &conn : cell->connections()) + { + if (!cell->output(conn.first)) + continue; - if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) { - IdString new_m_name = m->derive(design, cell->parameters, true); - if (new_m_name.empty()) - continue; - if (new_m_name != m->name) { - m = design->module(new_m_name); - blackbox_derivatives.insert(m); + SigSpec new_sig; + bool update_port = false; + + for (auto c : conn.second.chunks()) + { + Wire *w = c.wire; + + if (wand_wor_index.count(w) == 0) { + new_sig.append(c); + continue; + } + + Wire *t = module->addWire(NEW_ID, GetSize(c)); + new_sig.append(t); + update_port = true; + + if (wand_map.count(w)) { + SigSpec sig = SigSpec(State::S1, GetSize(w)); + sig.replace(c.offset, t); + wand_map.at(w).append(sig); + } else { + SigSpec sig = SigSpec(State::S0, GetSize(w)); + sig.replace(c.offset, t); + wor_map.at(w).append(sig); + } + } + + if (update_port) + cell->setPort(conn.first, new_sig); } } - for (auto &conn : cell->connections()) + for (auto w : wand_wor_index) { - Wire *w = m->wire(conn.first); + bool wand = wand_map.count(w); + SigSpec sigs = wand ? wand_map.at(w) : wor_map.at(w); - if (w == nullptr || w->port_id == 0) + if (GetSize(sigs) == 0) continue; - if (GetSize(conn.second) == 0) + if (GetSize(w) == 1) { + if (wand) + module->addReduceAnd(NEW_ID, sigs, w); + else + module->addReduceOr(NEW_ID, sigs, w); continue; + } - SigSpec sig = conn.second; - - if (!keep_portwidths && GetSize(w) != GetSize(conn.second)) - { - if (GetSize(w) < GetSize(conn.second)) - { - int n = GetSize(conn.second) - GetSize(w); - if (!w->port_input && w->port_output) - module->connect(sig.extract(GetSize(w), n), Const(0, n)); - sig.remove(GetSize(w), n); - } + SigSpec s = sigs.extract(0, GetSize(w)); + for (int i = GetSize(w); i < GetSize(sigs); i += GetSize(w)) { + if (wand) + s = module->And(NEW_ID, s, sigs.extract(i, GetSize(w))); else - { - int n = GetSize(w) - GetSize(conn.second); - if (w->port_input && !w->port_output) - sig.append(Const(0, n)); - else - sig.append(module->addWire(NEW_ID, n)); - } + s = module->Or(NEW_ID, s, sigs.extract(i, GetSize(w))); + } + module->connect(w, s); + } + + for (auto cell : module->cells()) + { + Module *m = design->module(cell->type); + + if (m == nullptr) + continue; - if (!conn.second.is_fully_const() || !w->port_input || w->port_output) - log_warning("Resizing cell port %s.%s.%s from %d bits to %d bits.\n", log_id(module), log_id(cell), - log_id(conn.first), GetSize(conn.second), GetSize(sig)); - cell->setPort(conn.first, sig); + if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) { + IdString new_m_name = m->derive(design, cell->parameters, true); + if (new_m_name.empty()) + continue; + if (new_m_name != m->name) { + m = design->module(new_m_name); + blackbox_derivatives.insert(m); + } } - for (int i = 0; i < GetSize(sig); i++) { - Wire *sigwire = sig[i].wire; - if (sigwire == nullptr) + for (auto &conn : cell->connections()) + { + Wire *w = m->wire(conn.first); + + if (w == nullptr || w->port_id == 0) + continue; + + if (GetSize(conn.second) == 0) continue; - if (sigwire->get_bool_attribute("\\wor") || sigwire->get_bool_attribute("\\wand")) { - if (w->port_output && !w->port_input) { - Cell *reduce = wlogic_map[sigwire]; - SigSpec reduce_in = reduce->getPort("\\A"); - int reduce_width = reduce->getParam("\\A_WIDTH").as_int(); - Wire *new_reduce_input = module->addWire( - stringf("$%s_in%d", reduce->name.c_str(), reduce_width)); - reduce_in.append(new_reduce_input); - reduce->setPort("\\A", reduce_in); - reduce->fixup_parameters(); - sig[i] = new_reduce_input; + SigSpec sig = conn.second; + + if (!keep_portwidths && GetSize(w) != GetSize(conn.second)) + { + if (GetSize(w) < GetSize(conn.second)) + { + int n = GetSize(conn.second) - GetSize(w); + if (!w->port_input && w->port_output) + module->connect(sig.extract(GetSize(w), n), Const(0, n)); + sig.remove(GetSize(w), n); + } + else + { + int n = GetSize(w) - GetSize(conn.second); + if (w->port_input && !w->port_output) + sig.append(Const(0, n)); + else + sig.append(module->addWire(NEW_ID, n)); } + + if (!conn.second.is_fully_const() || !w->port_input || w->port_output) + log_warning("Resizing cell port %s.%s.%s from %d bits to %d bits.\n", log_id(module), log_id(cell), + log_id(conn.first), GetSize(conn.second), GetSize(sig)); + cell->setPort(conn.first, sig); } - } - cell->setPort(conn.first, sig); - if (w->port_output && !w->port_input && sig.has_const()) - log_error("Output port %s.%s.%s (%s) is connected to constants: %s\n", - log_id(module), log_id(cell), log_id(conn.first), log_id(cell->type), log_signal(sig)); + if (w->port_output && !w->port_input && sig.has_const()) + log_error("Output port %s.%s.%s (%s) is connected to constants: %s\n", + log_id(module), log_id(cell), log_id(conn.first), log_id(cell->type), log_signal(sig)); + } } } -- cgit v1.2.3 From 3da5288ce096befb844476907a2c6020aae62b8b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 19 Jun 2019 11:49:20 +0200 Subject: Use input default values in hierarchy pass Signed-off-by: Clifford Wolf --- passes/hierarchy/hierarchy.cc | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 24e64a9b2..213437c01 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -591,6 +591,9 @@ struct HierarchyPass : public Pass { log(" module instances when the width does not match the module port. This\n"); log(" option disables this behavior.\n"); log("\n"); + log(" -nodefaults\n"); + log(" do not resolve input port default values\n"); + log("\n"); log(" -nokeep_asserts\n"); log(" per default this pass sets the \"keep\" attribute on all modules\n"); log(" that directly or indirectly contain one or more formal properties.\n"); @@ -645,6 +648,7 @@ struct HierarchyPass : public Pass { bool generate_mode = false; bool keep_positionals = false; bool keep_portwidths = false; + bool nodefaults = false; bool nokeep_asserts = false; std::vector generate_cells; std::vector generate_ports; @@ -712,6 +716,10 @@ struct HierarchyPass : public Pass { keep_portwidths = true; continue; } + if (args[argidx] == "-nodefaults") { + nodefaults = true; + continue; + } if (args[argidx] == "-nokeep_asserts") { nokeep_asserts = true; continue; @@ -940,6 +948,36 @@ struct HierarchyPass : public Pass { } } + if (!nodefaults) + { + dict> defaults_db; + + for (auto module : design->modules()) + for (auto wire : module->wires()) + if (wire->port_input && wire->attributes.count("\\defaultvalue")) + defaults_db[module->name][wire->name] = wire->attributes.at("\\defaultvalue"); + + for (auto module : design->modules()) + for (auto cell : module->cells()) + { + if (defaults_db.count(cell->type) == 0) + continue; + + if (keep_positionals) { + bool found_positionals = false; + for (auto &conn : cell->connections()) + if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') + found_positionals = true; + if (found_positionals) + continue; + } + + for (auto &it : defaults_db.at(cell->type)) + if (!cell->hasPort(it.first)) + cell->setPort(it.first, it.second); + } + } + std::set blackbox_derivatives; std::vector design_modules = design->modules(); -- cgit v1.2.3 From e38f40af5b7cdd5c8b896ffba17069bd65f01f29 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 6 Aug 2019 16:42:25 -0700 Subject: Use IdString::begins_with() --- passes/hierarchy/hierarchy.cc | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 213437c01..19bf531cf 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -48,7 +48,7 @@ void generate(RTLIL::Design *design, const std::vector &celltypes, RTLIL::Cell *cell = i2.second; if (design->has(cell->type)) continue; - if (cell->type.substr(0, 1) == "$" && cell->type.substr(0, 3) != "$__") + if (cell->type.begins_with("$__")) continue; for (auto &pattern : celltypes) if (patmatch(pattern.c_str(), RTLIL::unescape_id(cell->type).c_str())) @@ -143,7 +143,7 @@ void generate(RTLIL::Design *design, const std::vector &celltypes, // Return the "basic" type for an array item. std::string basic_cell_type(const std::string celltype, int pos[3] = nullptr) { std::string basicType = celltype; - if (celltype.substr(0, 7) == "$array:") { + if (celltype.compare(0, strlen("$array:"), "$array:")) { int pos_idx = celltype.find_first_of(':'); int pos_num = celltype.find_first_of(':', pos_idx + 1); int pos_type = celltype.find_first_of(':', pos_num + 1); @@ -194,14 +194,14 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check std::vector connections_to_add_name; std::vector connections_to_add_signal; - if (cell->type.substr(0, 7) == "$array:") { + if (cell->type.begins_with("$array:")) { int pos[3]; basic_cell_type(cell->type.str(), pos); int pos_idx = pos[0]; int pos_num = pos[1]; int pos_type = pos[2]; - int idx = atoi(cell->type.str().substr(pos_idx + 1, pos_num).c_str()); - int num = atoi(cell->type.str().substr(pos_num + 1, pos_type).c_str()); + int idx = std::stoi(cell->type.str().substr(pos_idx + 1, pos_num)); + int num = std::stoi(cell->type.str().substr(pos_num + 1, pos_type)); array_cells[cell] = std::pair(idx, num); cell->type = cell->type.str().substr(pos_type + 1); } @@ -422,8 +422,8 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check for (auto &conn : cell->connections_) { int conn_size = conn.second.size(); RTLIL::IdString portname = conn.first; - if (portname.substr(0, 1) == "$") { - int port_id = atoi(portname.substr(1).c_str()); + if (portname.begins_with("$")) { + int port_id = std::stoi(portname.substr(1)); for (auto &wire_it : mod->wires_) if (wire_it.second->port_id == port_id) { portname = wire_it.first; @@ -457,9 +457,8 @@ void hierarchy_worker(RTLIL::Design *design, std::setcells()) { std::string celltype = cell->type.str(); - if (celltype.substr(0, 7) == "$array:") { + if (celltype.compare(0, strlen("$array:"), "$array:")) celltype = basic_cell_type(celltype); - } if (design->module(celltype)) hierarchy_worker(design, used, design->module(celltype), indent+4); } @@ -521,9 +520,8 @@ int find_top_mod_score(Design *design, Module *module, dict &db) for (auto cell : module->cells()) { std::string celltype = cell->type.str(); // Is this an array instance - if (celltype.substr(0, 7) == "$array:") { + if (celltype.compare(0, strlen("$array:"), "$array:")) celltype = basic_cell_type(celltype); - } // Is this cell a module instance? auto instModule = design->module(celltype); // If there is no instance for this, issue a warning. -- cgit v1.2.3 From 234fcf1724941b5c4fa77cc0359d339ddd36aeb3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 6 Aug 2019 19:07:45 -0700 Subject: Fix typos --- passes/hierarchy/hierarchy.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 19bf531cf..ff5c3b6a1 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -143,7 +143,7 @@ void generate(RTLIL::Design *design, const std::vector &celltypes, // Return the "basic" type for an array item. std::string basic_cell_type(const std::string celltype, int pos[3] = nullptr) { std::string basicType = celltype; - if (celltype.compare(0, strlen("$array:"), "$array:")) { + if (celltype.compare(0, strlen("$array:"), "$array:") == 0) { int pos_idx = celltype.find_first_of(':'); int pos_num = celltype.find_first_of(':', pos_idx + 1); int pos_type = celltype.find_first_of(':', pos_num + 1); @@ -200,8 +200,8 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check int pos_idx = pos[0]; int pos_num = pos[1]; int pos_type = pos[2]; - int idx = std::stoi(cell->type.str().substr(pos_idx + 1, pos_num)); - int num = std::stoi(cell->type.str().substr(pos_num + 1, pos_type)); + int idx = std::stoi(cell->type.substr(pos_idx + 1, pos_num)); + int num = std::stoi(cell->type.substr(pos_num + 1, pos_type)); array_cells[cell] = std::pair(idx, num); cell->type = cell->type.str().substr(pos_type + 1); } @@ -457,7 +457,7 @@ void hierarchy_worker(RTLIL::Design *design, std::setcells()) { std::string celltype = cell->type.str(); - if (celltype.compare(0, strlen("$array:"), "$array:")) + if (celltype.compare(0, strlen("$array:"), "$array:") == 0) celltype = basic_cell_type(celltype); if (design->module(celltype)) hierarchy_worker(design, used, design->module(celltype), indent+4); @@ -520,7 +520,7 @@ int find_top_mod_score(Design *design, Module *module, dict &db) for (auto cell : module->cells()) { std::string celltype = cell->type.str(); // Is this an array instance - if (celltype.compare(0, strlen("$array:"), "$array:")) + if (celltype.compare(0, strlen("$array:"), "$array:") == 0) celltype = basic_cell_type(celltype); // Is this cell a module instance? auto instModule = design->module(celltype); -- cgit v1.2.3 From ee7c970367c68fe1a02a237ed01f2845a03cf9b2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 6 Aug 2019 19:08:33 -0700 Subject: IdString::str().substr() -> IdString::substr() --- passes/hierarchy/hierarchy.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index ff5c3b6a1..1319225ff 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -203,7 +203,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check int idx = std::stoi(cell->type.substr(pos_idx + 1, pos_num)); int num = std::stoi(cell->type.substr(pos_num + 1, pos_type)); array_cells[cell] = std::pair(idx, num); - cell->type = cell->type.str().substr(pos_type + 1); + cell->type = cell->type.substr(pos_type + 1); } dict interfaces_to_add_to_submodule; dict modports_used_in_submodule; -- cgit v1.2.3 From 48d0f994064557dc0832748e17133ee2eac88cbf Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 7 Aug 2019 11:09:17 -0700 Subject: stoi -> atoi --- passes/hierarchy/hierarchy.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 1319225ff..fd95b94b2 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -200,8 +200,8 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check int pos_idx = pos[0]; int pos_num = pos[1]; int pos_type = pos[2]; - int idx = std::stoi(cell->type.substr(pos_idx + 1, pos_num)); - int num = std::stoi(cell->type.substr(pos_num + 1, pos_type)); + int idx = atoi(cell->type.substr(pos_idx + 1, pos_num).c_str()); + int num = atoi(cell->type.substr(pos_num + 1, pos_type).c_str()); array_cells[cell] = std::pair(idx, num); cell->type = cell->type.substr(pos_type + 1); } @@ -423,7 +423,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check int conn_size = conn.second.size(); RTLIL::IdString portname = conn.first; if (portname.begins_with("$")) { - int port_id = std::stoi(portname.substr(1)); + int port_id = atoi(portname.substr(1).c_str()); for (auto &wire_it : mod->wires_) if (wire_it.second->port_id == port_id) { portname = wire_it.first; -- cgit v1.2.3 From 116c2496011aeeac9847d69af597a0db58209793 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 19:59:25 -0700 Subject: -auto-top should check $abstract (deferred) modules with (* top *) --- passes/hierarchy/hierarchy.cc | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index fd95b94b2..ad795c69f 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -808,6 +808,37 @@ struct HierarchyPass : public Pass { if (mod_it.second->get_bool_attribute("\\top")) top_mod = mod_it.second; + if (top_mod != nullptr && auto_top_mode) { + IdString abstract_id = top_mod->name; + IdString top_name = abstract_id; + if (top_name.begins_with("$abstract")) + top_name = top_name.substr(strlen("$abstract")); + top_mod = design->module(top_name); + + dict top_parameters; + for (auto ¶ : parameters) { + SigSpec sig_value; + if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second)) + log_cmd_error("Can't decode value '%s'!\n", para.second.c_str()); + top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const(); + } + + if (top_mod == nullptr && design->module(abstract_id)) + top_mod = design->module(design->module(abstract_id)->derive(design, top_parameters)); + else if (top_mod != nullptr && !top_parameters.empty()) + top_mod = design->module(top_mod->derive(design, top_parameters)); + + if (top_mod != nullptr && top_mod->name != top_name) { + Module *m = top_mod->clone(); + m->name = top_name; + Module *old_mod = design->module(top_name); + if (old_mod) + design->remove(old_mod); + design->add(m); + top_mod = m; + } + } + if (top_mod == nullptr && auto_top_mode) { log_header(design, "Finding top of design hierarchy..\n"); dict db; -- cgit v1.2.3 From d2306d7b1d9725fef2d1db4e205c1b0cb6c84715 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 3 Sep 2019 12:18:50 -0700 Subject: Adopt @cliffordwolf's suggestion --- passes/hierarchy/hierarchy.cc | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'passes/hierarchy/hierarchy.cc') diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index ad795c69f..d8a628448 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -808,12 +808,8 @@ struct HierarchyPass : public Pass { if (mod_it.second->get_bool_attribute("\\top")) top_mod = mod_it.second; - if (top_mod != nullptr && auto_top_mode) { - IdString abstract_id = top_mod->name; - IdString top_name = abstract_id; - if (top_name.begins_with("$abstract")) - top_name = top_name.substr(strlen("$abstract")); - top_mod = design->module(top_name); + if (top_mod != nullptr && top_mod->name.begins_with("$abstract")) { + IdString top_name = top_mod->name.substr(strlen("$abstract")); dict top_parameters; for (auto ¶ : parameters) { @@ -823,10 +819,7 @@ struct HierarchyPass : public Pass { top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const(); } - if (top_mod == nullptr && design->module(abstract_id)) - top_mod = design->module(design->module(abstract_id)->derive(design, top_parameters)); - else if (top_mod != nullptr && !top_parameters.empty()) - top_mod = design->module(top_mod->derive(design, top_parameters)); + top_mod = design->module(top_mod->derive(design, top_parameters)); if (top_mod != nullptr && top_mod->name != top_name) { Module *m = top_mod->clone(); -- cgit v1.2.3