diff options
author | Ruben Undheim <ruben.undheim@gmail.com> | 2018-10-20 11:58:25 +0200 |
---|---|---|
committer | Ruben Undheim <ruben.undheim@gmail.com> | 2018-10-20 11:58:25 +0200 |
commit | 397dfccb304a12a40d34c4454a5cb4acee8be75f (patch) | |
tree | 39f2bdcbfbc62de55f7333c0bcfb509735bf561a /passes/hierarchy | |
parent | d9a438101298710b9dadd4e7a1cb0041e8ba4199 (diff) | |
download | yosys-397dfccb304a12a40d34c4454a5cb4acee8be75f.tar.gz yosys-397dfccb304a12a40d34c4454a5cb4acee8be75f.tar.bz2 yosys-397dfccb304a12a40d34c4454a5cb4acee8be75f.zip |
Support for SystemVerilog interfaces as a port in the top level module + test case
Diffstat (limited to 'passes/hierarchy')
-rw-r--r-- | passes/hierarchy/hierarchy.cc | 41 |
1 files changed, 36 insertions, 5 deletions
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<RTLIL::Cell*, std::pair<int, int>> 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<RTLIL::IdString, RTLIL::Module*> 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<RTLIL::Wire*> 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) { |