aboutsummaryrefslogtreecommitdiffstats
path: root/passes/hierarchy
diff options
context:
space:
mode:
authorRuben Undheim <ruben.undheim@gmail.com>2018-10-20 11:58:25 +0200
committerRuben Undheim <ruben.undheim@gmail.com>2018-10-20 11:58:25 +0200
commit397dfccb304a12a40d34c4454a5cb4acee8be75f (patch)
tree39f2bdcbfbc62de55f7333c0bcfb509735bf561a /passes/hierarchy
parentd9a438101298710b9dadd4e7a1cb0041e8ba4199 (diff)
downloadyosys-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.cc41
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) {