3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-06-06 14:13:23 +00:00

Support for 'modports' for System Verilog interfaces

This commit is contained in:
Ruben Undheim 2018-10-12 20:58:37 +02:00
parent 75009ada3c
commit 458a94059e
8 changed files with 121 additions and 14 deletions

View file

@ -1118,7 +1118,7 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT
}
// create a new parametric module (when needed) and return the name of the generated module - WITH support for interfaces
RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, bool mayfail)
RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail)
{
AstNode *new_ast = NULL;
std::string modname = derive_common(design, parameters, &new_ast, mayfail);
@ -1143,14 +1143,46 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
for(auto &intf : interfaces) {
RTLIL::Module * intfmodule = intf.second;
std::string intfname = intf.first.str();
AstNode *modport = NULL;
if (modports.count(intfname) > 0) {
std::string interface_modport = modports.at(intfname).str();
AstModule *ast_module_of_interface = (AstModule*)intfmodule;
AstNode *ast_node_of_interface = ast_module_of_interface->ast;
for (auto &ch : ast_node_of_interface->children) {
if (ch->type == AST_MODPORT) {
if (ch->str == interface_modport) {
modport = ch;
}
}
}
}
for (auto &wire_it : intfmodule->wires_){
AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, AstNode::mkconst_int(wire_it.second->width -1, true), AstNode::mkconst_int(0, true)));
std::string origname = log_id(wire_it.first);
std::string newname = intfname + "." + origname;
wire->str = newname;
wire->is_input = true;
wire->is_output = true;
new_ast->children.push_back(wire);
if (modport != NULL) {
bool found_in_modport = false;
for (auto &ch : modport->children) {
if (ch->type == AST_MODPORTMEMBER) {
std::string compare_name = "\\" + origname;
if (ch->str == compare_name) {
found_in_modport = true;
wire->is_input = ch->is_input;
wire->is_output = ch->is_output;
break;
}
}
}
if (found_in_modport) { // If not found in modport, do not create port
new_ast->children.push_back(wire);
}
}
else { // If no modport, set inout
wire->is_input = true;
wire->is_output = true;
new_ast->children.push_back(wire);
}
}
}