mirror of https://github.com/YosysHQ/yosys.git
commit
f25d0de6f8
2
Makefile
2
Makefile
|
@ -573,6 +573,7 @@ test: $(TARGETS) $(EXTRA_TARGETS)
|
||||||
+cd tests/bram && bash run-test.sh $(SEEDOPT)
|
+cd tests/bram && bash run-test.sh $(SEEDOPT)
|
||||||
+cd tests/various && bash run-test.sh
|
+cd tests/various && bash run-test.sh
|
||||||
+cd tests/sat && bash run-test.sh
|
+cd tests/sat && bash run-test.sh
|
||||||
|
+cd tests/svinterfaces && bash run-test.sh $(SEEDOPT)
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo " Passed \"make test\"."
|
@echo " Passed \"make test\"."
|
||||||
@echo ""
|
@echo ""
|
||||||
|
@ -655,6 +656,7 @@ clean:
|
||||||
rm -rf tests/sat/*.log tests/techmap/*.log tests/various/*.log
|
rm -rf tests/sat/*.log tests/techmap/*.log tests/various/*.log
|
||||||
rm -rf tests/bram/temp tests/fsm/temp tests/realmath/temp tests/share/temp tests/smv/temp
|
rm -rf tests/bram/temp tests/fsm/temp tests/realmath/temp tests/share/temp tests/smv/temp
|
||||||
rm -rf vloghtb/Makefile vloghtb/refdat vloghtb/rtl vloghtb/scripts vloghtb/spec vloghtb/check_yosys vloghtb/vloghammer_tb.tar.bz2 vloghtb/temp vloghtb/log_test_*
|
rm -rf vloghtb/Makefile vloghtb/refdat vloghtb/rtl vloghtb/scripts vloghtb/spec vloghtb/check_yosys vloghtb/vloghammer_tb.tar.bz2 vloghtb/temp vloghtb/log_test_*
|
||||||
|
rm -f tests/svinterfaces/*.log_stdout tests/svinterfaces/*.log_stderr tests/svinterfaces/dut_result.txt tests/svinterfaces/reference_result.txt tests/svinterfaces/a.out tests/svinterfaces/*_syn.v tests/svinterfaces/*.diff
|
||||||
rm -f tests/tools/cmp_tbdata
|
rm -f tests/tools/cmp_tbdata
|
||||||
|
|
||||||
clean-abc:
|
clean-abc:
|
||||||
|
|
|
@ -904,7 +904,7 @@ RTLIL::Const AstNode::realAsConst(int width)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new AstModule from an AST_MODULE AST node
|
// create a new AstModule from an AST_MODULE AST node
|
||||||
static AstModule* process_module(AstNode *ast, bool defer)
|
static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast = NULL)
|
||||||
{
|
{
|
||||||
log_assert(ast->type == AST_MODULE || ast->type == AST_INTERFACE);
|
log_assert(ast->type == AST_MODULE || ast->type == AST_INTERFACE);
|
||||||
|
|
||||||
|
@ -920,7 +920,11 @@ static AstModule* process_module(AstNode *ast, bool defer)
|
||||||
current_module->set_bool_attribute("\\cells_not_processed");
|
current_module->set_bool_attribute("\\cells_not_processed");
|
||||||
|
|
||||||
current_ast_mod = ast;
|
current_ast_mod = ast;
|
||||||
AstNode *ast_before_simplify = ast->clone();
|
AstNode *ast_before_simplify;
|
||||||
|
if (original_ast != NULL)
|
||||||
|
ast_before_simplify = original_ast;
|
||||||
|
else
|
||||||
|
ast_before_simplify = ast->clone();
|
||||||
|
|
||||||
if (flag_dump_ast1) {
|
if (flag_dump_ast1) {
|
||||||
log("Dumping Verilog AST before simplification:\n");
|
log("Dumping Verilog AST before simplification:\n");
|
||||||
|
@ -1087,6 +1091,84 @@ AstModule::~AstModule()
|
||||||
delete ast;
|
delete ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// An interface port with modport is specified like this:
|
||||||
|
// <interface_name>.<modport_name>
|
||||||
|
// This function splits the interface_name from the modport_name, and fails if it is not a valid combination
|
||||||
|
std::pair<std::string,std::string> AST::split_modport_from_type(std::string name_type)
|
||||||
|
{
|
||||||
|
std::string interface_type = "";
|
||||||
|
std::string interface_modport = "";
|
||||||
|
size_t ndots = std::count(name_type.begin(), name_type.end(), '.');
|
||||||
|
// Separate the interface instance name from any modports:
|
||||||
|
if (ndots == 0) { // Does not have modport
|
||||||
|
interface_type = name_type;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::stringstream name_type_stream(name_type);
|
||||||
|
std::string segment;
|
||||||
|
std::vector<std::string> seglist;
|
||||||
|
while(std::getline(name_type_stream, segment, '.')) {
|
||||||
|
seglist.push_back(segment);
|
||||||
|
}
|
||||||
|
if (ndots == 1) { // Has modport
|
||||||
|
interface_type = seglist[0];
|
||||||
|
interface_modport = seglist[1];
|
||||||
|
}
|
||||||
|
else { // Erroneous port type
|
||||||
|
log_error("More than two '.' in signal port type (%s)\n", name_type.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::pair<std::string,std::string>(interface_type, interface_modport);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AstNode * AST::find_modport(AstNode *intf, std::string name)
|
||||||
|
{
|
||||||
|
for (auto &ch : intf->children)
|
||||||
|
if (ch->type == AST_MODPORT)
|
||||||
|
if (ch->str == name) // Modport found
|
||||||
|
return ch;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over all wires in an interface and add them as wires in the AST module:
|
||||||
|
void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule, std::string intfname, AstNode *modport)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
if (modport != NULL) {
|
||||||
|
bool found_in_modport = false;
|
||||||
|
// Search for the current wire in the wire list for the current modport
|
||||||
|
for (auto &ch : modport->children) {
|
||||||
|
if (ch->type == AST_MODPORTMEMBER) {
|
||||||
|
std::string compare_name = "\\" + origname;
|
||||||
|
if (ch->str == compare_name) { // Found signal. The modport decides whether it is input or output
|
||||||
|
found_in_modport = true;
|
||||||
|
wire->is_input = ch->is_input;
|
||||||
|
wire->is_output = ch->is_output;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found_in_modport) {
|
||||||
|
module_ast->children.push_back(wire);
|
||||||
|
}
|
||||||
|
else { // If not found in modport, do not create port
|
||||||
|
delete wire;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // If no modport, set inout
|
||||||
|
wire->is_input = true;
|
||||||
|
wire->is_output = true;
|
||||||
|
module_ast->children.push_back(wire);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// When an interface instance is found in a module, the whole RTLIL for the module will be rederived again
|
// When an interface instance is found in a module, the whole RTLIL for the module will be rederived again
|
||||||
// from AST. The interface members are copied into the AST module with the prefix of the interface.
|
// from AST. The interface members are copied into the AST module with the prefix of the interface.
|
||||||
void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module*> local_interfaces)
|
void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module*> local_interfaces)
|
||||||
|
@ -1105,6 +1187,49 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AstNode *ast_before_replacing_interface_ports = new_ast->clone();
|
||||||
|
|
||||||
|
// Explode all interface ports. Note this will only have an effect on 'top
|
||||||
|
// level' modules. Other sub-modules will have their interface ports
|
||||||
|
// exploded via the derive(..) function
|
||||||
|
for (size_t i =0; i<new_ast->children.size(); i++)
|
||||||
|
{
|
||||||
|
AstNode *ch2 = new_ast->children[i];
|
||||||
|
if (ch2->type == AST_INTERFACEPORT) { // Is an interface port
|
||||||
|
std::string name_port = ch2->str; // Name of the interface port
|
||||||
|
if (ch2->children.size() > 0) {
|
||||||
|
for(size_t j=0; j<ch2->children.size();j++) {
|
||||||
|
AstNode *ch = ch2->children[j];
|
||||||
|
if(ch->type == AST_INTERFACEPORTTYPE) { // Found the AST node containing the type of the interface
|
||||||
|
std::pair<std::string,std::string> res = split_modport_from_type(ch->str);
|
||||||
|
std::string interface_type = res.first;
|
||||||
|
std::string interface_modport = res.second; // Is "", if no modport
|
||||||
|
if (design->modules_.count(interface_type) > 0) {
|
||||||
|
// Add a cell to the module corresponding to the interface port such that
|
||||||
|
// it can further propagated down if needed:
|
||||||
|
AstNode *celltype_for_intf = new AstNode(AST_CELLTYPE);
|
||||||
|
celltype_for_intf->str = interface_type;
|
||||||
|
AstNode *cell_for_intf = new AstNode(AST_CELL, celltype_for_intf);
|
||||||
|
cell_for_intf->str = name_port + "_inst_from_top_dummy";
|
||||||
|
new_ast->children.push_back(cell_for_intf);
|
||||||
|
|
||||||
|
// Get all members of this non-overridden dummy interface instance:
|
||||||
|
RTLIL::Module *intfmodule = design->modules_[interface_type]; // All interfaces should at this point in time (assuming
|
||||||
|
// reprocess_module is called from the hierarchy pass) be
|
||||||
|
// present in design->modules_
|
||||||
|
AstModule *ast_module_of_interface = (AstModule*)intfmodule;
|
||||||
|
std::string interface_modport_compare_str = "\\" + interface_modport;
|
||||||
|
AstNode *modport = find_modport(ast_module_of_interface->ast, interface_modport_compare_str); // modport == NULL if no modport
|
||||||
|
// Iterate over all wires in the interface and add them to the module:
|
||||||
|
explode_interface_port(new_ast, intfmodule, name_port, modport);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The old module will be deleted. Rename and mark for deletion:
|
// The old module will be deleted. Rename and mark for deletion:
|
||||||
std::string original_name = this->name.str();
|
std::string original_name = this->name.str();
|
||||||
std::string changed_name = original_name + "_before_replacing_local_interfaces";
|
std::string changed_name = original_name + "_before_replacing_local_interfaces";
|
||||||
|
@ -1119,7 +1244,8 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate RTLIL from AST for the new module and add to the design:
|
// Generate RTLIL from AST for the new module and add to the design:
|
||||||
AstModule *newmod = process_module(new_ast, false);
|
AstModule *newmod = process_module(new_ast, false, ast_before_replacing_interface_ports);
|
||||||
|
delete(new_ast);
|
||||||
design->add(newmod);
|
design->add(newmod);
|
||||||
RTLIL::Module* mod = design->module(original_name);
|
RTLIL::Module* mod = design->module(original_name);
|
||||||
if (is_top)
|
if (is_top)
|
||||||
|
@ -1164,47 +1290,10 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
|
||||||
std::string interface_modport = modports.at(intfname).str();
|
std::string interface_modport = modports.at(intfname).str();
|
||||||
AstModule *ast_module_of_interface = (AstModule*)intfmodule;
|
AstModule *ast_module_of_interface = (AstModule*)intfmodule;
|
||||||
AstNode *ast_node_of_interface = ast_module_of_interface->ast;
|
AstNode *ast_node_of_interface = ast_module_of_interface->ast;
|
||||||
for (auto &ch : ast_node_of_interface->children) {
|
modport = find_modport(ast_node_of_interface, interface_modport);
|
||||||
if (ch->type == AST_MODPORT) {
|
|
||||||
if (ch->str == interface_modport) { // Modport found
|
|
||||||
modport = ch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Iterate over all wires in the interface and add them to the module:
|
// Iterate over all wires in the interface and add them to the module:
|
||||||
for (auto &wire_it : intfmodule->wires_){
|
explode_interface_port(new_ast, intfmodule, intfname, modport);
|
||||||
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;
|
|
||||||
if (modport != NULL) {
|
|
||||||
bool found_in_modport = false;
|
|
||||||
// Search for the current wire in the wire list for the current modport
|
|
||||||
for (auto &ch : modport->children) {
|
|
||||||
if (ch->type == AST_MODPORTMEMBER) {
|
|
||||||
std::string compare_name = "\\" + origname;
|
|
||||||
if (ch->str == compare_name) { // Found signal. The modport decides whether it is input or output
|
|
||||||
found_in_modport = true;
|
|
||||||
wire->is_input = ch->is_input;
|
|
||||||
wire->is_output = ch->is_output;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found_in_modport) {
|
|
||||||
new_ast->children.push_back(wire);
|
|
||||||
}
|
|
||||||
else { // If not found in modport, do not create port
|
|
||||||
delete wire;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { // If no modport, set inout
|
|
||||||
wire->is_input = true;
|
|
||||||
wire->is_output = true;
|
|
||||||
new_ast->children.push_back(wire);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
design->add(process_module(new_ast, false));
|
design->add(process_module(new_ast, false));
|
||||||
|
|
|
@ -308,6 +308,11 @@ namespace AST
|
||||||
|
|
||||||
// call a DPI function
|
// call a DPI function
|
||||||
AstNode *dpi_call(const std::string &rtype, const std::string &fname, const std::vector<std::string> &argtypes, const std::vector<AstNode*> &args);
|
AstNode *dpi_call(const std::string &rtype, const std::string &fname, const std::vector<std::string> &argtypes, const std::vector<AstNode*> &args);
|
||||||
|
|
||||||
|
// Helper functions related to handling SystemVerilog interfaces
|
||||||
|
std::pair<std::string,std::string> split_modport_from_type(std::string name_type);
|
||||||
|
AstNode * find_modport(AstNode *intf, std::string name);
|
||||||
|
void explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule, std::string intfname, AstNode *modport);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace AST_INTERNAL
|
namespace AST_INTERNAL
|
||||||
|
|
|
@ -870,27 +870,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
if (children.size() > 0) {
|
if (children.size() > 0) {
|
||||||
for(size_t i=0; i<children.size();i++) {
|
for(size_t i=0; i<children.size();i++) {
|
||||||
if(children[i]->type == AST_INTERFACEPORTTYPE) {
|
if(children[i]->type == AST_INTERFACEPORTTYPE) {
|
||||||
std::string name_type = children[i]->str;
|
std::pair<std::string,std::string> res = AST::split_modport_from_type(children[i]->str);
|
||||||
size_t ndots = std::count(name_type.begin(), name_type.end(), '.');
|
wire->attributes["\\interface_type"] = res.first;
|
||||||
// Separate the interface instance name from any modports:
|
if (res.second != "")
|
||||||
if (ndots == 0) { // Does not have modport
|
wire->attributes["\\interface_modport"] = res.second;
|
||||||
wire->attributes["\\interface_type"] = name_type;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
std::stringstream name_type_stream(name_type);
|
|
||||||
std::string segment;
|
|
||||||
std::vector<std::string> seglist;
|
|
||||||
while(std::getline(name_type_stream, segment, '.')) {
|
|
||||||
seglist.push_back(segment);
|
|
||||||
}
|
|
||||||
if (ndots == 1) { // Has modport
|
|
||||||
wire->attributes["\\interface_type"] = seglist[0];
|
|
||||||
wire->attributes["\\interface_modport"] = seglist[1];
|
|
||||||
}
|
|
||||||
else { // Erroneous port type
|
|
||||||
log_error("More than two '.' in signal port type (%s)\n", name_type.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1100,8 +1083,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
log_file_warning(filename, linenum, "Range select out of bounds on signal `%s': Setting result bit to undef.\n",
|
log_file_warning(filename, linenum, "Range select out of bounds on signal `%s': Setting result bit to undef.\n",
|
||||||
str.c_str());
|
str.c_str());
|
||||||
else
|
else
|
||||||
log_file_warning(filename, linenum, "Range select out of bounds on signal `%s': Setting all %d result bits to undef.\n",
|
log_file_warning(filename, linenum, "Range select [%d:%d] out of bounds on signal `%s': Setting all %d result bits to undef.\n",
|
||||||
str.c_str(), chunk.width);
|
children[0]->range_left, children[0]->range_right, str.c_str(), chunk.width);
|
||||||
chunk = RTLIL::SigChunk(RTLIL::State::Sx, chunk.width);
|
chunk = RTLIL::SigChunk(RTLIL::State::Sx, chunk.width);
|
||||||
} else {
|
} else {
|
||||||
if (chunk.width + chunk.offset > source_width) {
|
if (chunk.width + chunk.offset > source_width) {
|
||||||
|
@ -1114,11 +1097,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
chunk.offset += add_undef_bits_lsb;
|
chunk.offset += add_undef_bits_lsb;
|
||||||
}
|
}
|
||||||
if (add_undef_bits_lsb)
|
if (add_undef_bits_lsb)
|
||||||
log_file_warning(filename, linenum, "Range select out of bounds on signal `%s': Setting %d LSB bits to undef.\n",
|
log_file_warning(filename, linenum, "Range [%d:%d] select out of bounds on signal `%s': Setting %d LSB bits to undef.\n",
|
||||||
str.c_str(), add_undef_bits_lsb);
|
children[0]->range_left, children[0]->range_right, str.c_str(), add_undef_bits_lsb);
|
||||||
if (add_undef_bits_msb)
|
if (add_undef_bits_msb)
|
||||||
log_file_warning(filename, linenum, "Range select out of bounds on signal `%s': Setting %d MSB bits to undef.\n",
|
log_file_warning(filename, linenum, "Range [%d:%d] select out of bounds on signal `%s': Setting %d MSB bits to undef.\n",
|
||||||
str.c_str(), add_undef_bits_msb);
|
children[0]->range_left, children[0]->range_right, str.c_str(), add_undef_bits_msb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::map<RTLIL::Cell*, std::pair<int, int>> array_cells;
|
||||||
std::string filename;
|
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':
|
// Always keep track of all derived interfaces available in the current module in 'interfaces_in_module':
|
||||||
dict<RTLIL::IdString, RTLIL::Module*> interfaces_in_module;
|
dict<RTLIL::IdString, RTLIL::Module*> interfaces_in_module;
|
||||||
for (auto &cell_it : module->cells_)
|
for (auto &cell_it : module->cells_)
|
||||||
|
@ -244,8 +255,17 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
|
||||||
RTLIL::IdString interface_name = interface_name_str;
|
RTLIL::IdString interface_name = interface_name_str;
|
||||||
bool not_found_interface = false;
|
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(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
|
// Check if the interface instance is present in module:
|
||||||
RTLIL::Module *mod_replace_ports = interfaces_in_module.at(interface_name);
|
// 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) {
|
||||||
|
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.
|
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_name1 = conn.first.str() + "." + log_id(mod_wire.first);
|
||||||
std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire.first);
|
std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire.first);
|
||||||
|
@ -259,7 +279,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
connections_to_remove.push_back(conn.first);
|
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
|
// Add modports to a dict which will be passed to AstModule::derive
|
||||||
if (interface_modport != "") {
|
if (interface_modport != "") {
|
||||||
|
@ -363,8 +383,8 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
|
||||||
module->attributes.erase("\\cells_not_processed");
|
module->attributes.erase("\\cells_not_processed");
|
||||||
|
|
||||||
|
|
||||||
// If any interface instances were found in the module, we need to rederive it completely:
|
// If any interface instances or interface ports 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 ((interfaces_in_module.size() > 0 || has_interface_ports) && !module->get_bool_attribute("\\interfaces_replaced_in_module")) {
|
||||||
module->reprocess_module(design, interfaces_in_module);
|
module->reprocess_module(design, interfaces_in_module);
|
||||||
return did_something;
|
return did_something;
|
||||||
}
|
}
|
||||||
|
@ -438,6 +458,20 @@ void hierarchy_clean(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib)
|
||||||
for (auto &it : design->modules_)
|
for (auto &it : design->modules_)
|
||||||
if (used.count(it.second) == 0)
|
if (used.count(it.second) == 0)
|
||||||
del_modules.push_back(it.second);
|
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;
|
int del_counter = 0;
|
||||||
for (auto mod : del_modules) {
|
for (auto mod : del_modules) {
|
||||||
|
|
|
@ -623,6 +623,7 @@ grow_read_ports:;
|
||||||
pi.sig_addr = SigSpec();
|
pi.sig_addr = SigSpec();
|
||||||
pi.sig_data = SigSpec();
|
pi.sig_data = SigSpec();
|
||||||
pi.sig_en = SigSpec();
|
pi.sig_en = SigSpec();
|
||||||
|
pi.make_outreg = false;
|
||||||
}
|
}
|
||||||
new_portinfos.push_back(pi);
|
new_portinfos.push_back(pi);
|
||||||
if (pi.dupidx == dup_count-1) {
|
if (pi.dupidx == dup_count-1) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/dram.txt))
|
||||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/brams_map.v))
|
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/brams_map.v))
|
||||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/bram.txt))
|
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/bram.txt))
|
||||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/arith_map.v))
|
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/arith_map.v))
|
||||||
|
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/latches_map.v))
|
||||||
|
|
||||||
EXTRA_OBJS += techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk
|
EXTRA_OBJS += techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk
|
||||||
.SECONDARY: techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk
|
.SECONDARY: techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk
|
||||||
|
|
|
@ -265,16 +265,18 @@ module TRELLIS_IO(
|
||||||
output O
|
output O
|
||||||
);
|
);
|
||||||
parameter DIR = "INPUT";
|
parameter DIR = "INPUT";
|
||||||
|
reg T_pd;
|
||||||
|
always @(*) if (T === 1'bz) T_pd <= 1'b0; else T_pd <= T;
|
||||||
|
|
||||||
generate
|
generate
|
||||||
if (DIR == "INPUT") begin
|
if (DIR == "INPUT") begin
|
||||||
assign B = 1'bz;
|
assign B = 1'bz;
|
||||||
assign O = B;
|
assign O = B;
|
||||||
end else if (DIR == "OUTPUT") begin
|
end else if (DIR == "OUTPUT") begin
|
||||||
assign B = T ? 1'bz : I;
|
assign B = T_pd ? 1'bz : I;
|
||||||
assign O = 1'bx;
|
assign O = 1'bx;
|
||||||
end else if (DIR == "INOUT") begin
|
end else if (DIR == "BIDIR") begin
|
||||||
assign B = T ? 1'bz : I;
|
assign B = T_pd ? 1'bz : I;
|
||||||
assign O = B;
|
assign O = B;
|
||||||
end else begin
|
end else begin
|
||||||
ERROR_UNKNOWN_IO_MODE error();
|
ERROR_UNKNOWN_IO_MODE error();
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
module \$_DLATCH_N_ (E, D, Q);
|
||||||
|
wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
|
||||||
|
input E, D;
|
||||||
|
output Q = !E ? D : Q;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module \$_DLATCH_P_ (E, D, Q);
|
||||||
|
wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
|
||||||
|
input E, D;
|
||||||
|
output Q = E ? D : Q;
|
||||||
|
endmodule
|
|
@ -266,10 +266,7 @@ struct SynthEcp5Pass : public ScriptPass
|
||||||
if (abc2 || help_mode) {
|
if (abc2 || help_mode) {
|
||||||
run("abc", " (only if -abc2)");
|
run("abc", " (only if -abc2)");
|
||||||
}
|
}
|
||||||
//TODO
|
|
||||||
#if 0
|
|
||||||
run("techmap -map +/ecp5/latches_map.v");
|
run("techmap -map +/ecp5/latches_map.v");
|
||||||
#endif
|
|
||||||
if (nomux)
|
if (nomux)
|
||||||
run("abc -lut 4");
|
run("abc -lut 4");
|
||||||
else
|
else
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
#/bin/bash -e
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
./runone.sh svinterface1
|
||||||
|
./runone.sh svinterface_at_top
|
|
@ -0,0 +1,44 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
TESTNAME=$1
|
||||||
|
|
||||||
|
STDOUTFILE=${TESTNAME}.log_stdout
|
||||||
|
STDERRFILE=${TESTNAME}.log_stderr
|
||||||
|
|
||||||
|
echo "" > $STDOUTFILE
|
||||||
|
echo "" > $STDERRFILE
|
||||||
|
|
||||||
|
echo -n "Test: ${TESTNAME} -> "
|
||||||
|
|
||||||
|
$PWD/../../yosys -p "read_verilog -sv ${TESTNAME}.sv ; hierarchy -check -top TopModule ; synth ; write_verilog ${TESTNAME}_syn.v" >> $STDOUTFILE >> $STDERRFILE
|
||||||
|
$PWD/../../yosys -p "read_verilog -sv ${TESTNAME}_ref.v ; hierarchy -check -top TopModule ; synth ; write_verilog ${TESTNAME}_ref_syn.v" >> $STDOUTFILE >> $STDERRFILE
|
||||||
|
|
||||||
|
rm -f a.out reference_result.txt dut_result.txt
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
iverilog -g2012 ${TESTNAME}_syn.v
|
||||||
|
iverilog -g2012 ${TESTNAME}_ref_syn.v
|
||||||
|
|
||||||
|
set +e
|
||||||
|
iverilog -g2012 ${TESTNAME}_tb.v ${TESTNAME}_ref_syn.v
|
||||||
|
./a.out
|
||||||
|
mv output.txt reference_result.txt
|
||||||
|
if [ -f ${TESTNAME}_wrapper.v ] ; then
|
||||||
|
iverilog -g2012 ${TESTNAME}_tb_wrapper.v ${TESTNAME}_syn.v
|
||||||
|
else
|
||||||
|
iverilog -g2012 ${TESTNAME}_tb.v ${TESTNAME}_syn.v
|
||||||
|
fi
|
||||||
|
./a.out
|
||||||
|
mv output.txt dut_result.txt
|
||||||
|
|
||||||
|
diff reference_result.txt dut_result.txt > ${TESTNAME}.diff
|
||||||
|
RET=$?
|
||||||
|
if [ "$RET" != "0" ] ; then
|
||||||
|
echo "ERROR!"
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "ok"
|
||||||
|
exit 0
|
|
@ -3,8 +3,11 @@
|
||||||
module TopModule(
|
module TopModule(
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic rst,
|
input logic rst,
|
||||||
|
output logic [21:0] outOther,
|
||||||
input logic [1:0] sig,
|
input logic [1:0] sig,
|
||||||
output logic [1:0] sig_out);
|
input logic flip,
|
||||||
|
output logic [1:0] sig_out,
|
||||||
|
output logic [15:0] passThrough);
|
||||||
|
|
||||||
MyInterface #(.WIDTH(4)) MyInterfaceInstance();
|
MyInterface #(.WIDTH(4)) MyInterfaceInstance();
|
||||||
|
|
||||||
|
@ -12,14 +15,16 @@ module TopModule(
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
.u_MyInterface(MyInterfaceInstance),
|
.u_MyInterface(MyInterfaceInstance),
|
||||||
|
.outOther(outOther),
|
||||||
.sig (sig)
|
.sig (sig)
|
||||||
);
|
);
|
||||||
|
|
||||||
assign sig_out = MyInterfaceInstance.mysig_out;
|
assign sig_out = MyInterfaceInstance.mysig_out;
|
||||||
|
|
||||||
|
|
||||||
assign MyInterfaceInstance.setting = 1;
|
assign MyInterfaceInstance.setting = flip;
|
||||||
// assign MyInterfaceInstance.other_setting[2:0] = 3'b101;
|
|
||||||
|
assign passThrough = MyInterfaceInstance.passThrough;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -32,16 +37,20 @@ interface MyInterface #(
|
||||||
|
|
||||||
logic [1:0] mysig_out;
|
logic [1:0] mysig_out;
|
||||||
|
|
||||||
|
logic [15:0] passThrough;
|
||||||
|
|
||||||
modport submodule1 (
|
modport submodule1 (
|
||||||
input setting,
|
input setting,
|
||||||
output other_setting,
|
output other_setting,
|
||||||
output mysig_out
|
output mysig_out,
|
||||||
|
output passThrough
|
||||||
);
|
);
|
||||||
|
|
||||||
modport submodule2 (
|
modport submodule2 (
|
||||||
input setting,
|
input setting,
|
||||||
output other_setting,
|
output other_setting,
|
||||||
input mysig_out
|
input mysig_out,
|
||||||
|
output passThrough
|
||||||
);
|
);
|
||||||
|
|
||||||
endinterface
|
endinterface
|
||||||
|
@ -51,7 +60,8 @@ module SubModule1(
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic rst,
|
input logic rst,
|
||||||
MyInterface.submodule1 u_MyInterface,
|
MyInterface.submodule1 u_MyInterface,
|
||||||
input logic [1:0] sig
|
input logic [1:0] sig,
|
||||||
|
output logic [21:0] outOther
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -71,9 +81,14 @@ module SubModule1(
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
.u_MyInterfaceInSub2(u_MyInterface),
|
.u_MyInterfaceInSub2(u_MyInterface),
|
||||||
.sig (sig)
|
.u_MyInterfaceInSub3(MyInterfaceInstanceInSub)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assign outOther = MyInterfaceInstanceInSub.other_setting;
|
||||||
|
|
||||||
|
assign MyInterfaceInstanceInSub.setting = 0;
|
||||||
|
assign MyInterfaceInstanceInSub.mysig_out = sig;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module SubModule2(
|
module SubModule2(
|
||||||
|
@ -81,10 +96,22 @@ module SubModule2(
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic rst,
|
input logic rst,
|
||||||
MyInterface.submodule2 u_MyInterfaceInSub2,
|
MyInterface.submodule2 u_MyInterfaceInSub2,
|
||||||
input logic [1:0] sig
|
MyInterface.submodule2 u_MyInterfaceInSub3
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
assign u_MyInterfaceInSub2.other_setting[2:0] = 9;
|
always_comb begin
|
||||||
|
if (u_MyInterfaceInSub3.mysig_out == 2'b00)
|
||||||
|
u_MyInterfaceInSub3.other_setting[21:0] = 1000;
|
||||||
|
else if (u_MyInterfaceInSub3.mysig_out == 2'b01)
|
||||||
|
u_MyInterfaceInSub3.other_setting[21:0] = 2000;
|
||||||
|
else if (u_MyInterfaceInSub3.mysig_out == 2'b10)
|
||||||
|
u_MyInterfaceInSub3.other_setting[21:0] = 3000;
|
||||||
|
else
|
||||||
|
u_MyInterfaceInSub3.other_setting[21:0] = 4000;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign u_MyInterfaceInSub2.passThrough[7:0] = 124;
|
||||||
|
assign u_MyInterfaceInSub2.passThrough[15:8] = 200;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
|
@ -0,0 +1,107 @@
|
||||||
|
|
||||||
|
module TopModule(
|
||||||
|
input logic clk,
|
||||||
|
input logic rst,
|
||||||
|
input logic [1:0] sig,
|
||||||
|
input logic flip,
|
||||||
|
output logic [15:0] passThrough,
|
||||||
|
output logic [21:0] outOther,
|
||||||
|
output logic [1:0] sig_out);
|
||||||
|
|
||||||
|
|
||||||
|
logic MyInterfaceInstance_setting;
|
||||||
|
logic [3:0] MyInterfaceInstance_other_setting;
|
||||||
|
logic [1:0] MyInterfaceInstance_mysig_out;
|
||||||
|
|
||||||
|
SubModule1 u_SubModule1 (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.u_MyInterface_setting(MyInterfaceInstance_setting),
|
||||||
|
.u_MyInterface_mysig_out(MyInterfaceInstance_mysig_out),
|
||||||
|
.u_MyInterface_other_setting(MyInterfaceInstance_other_setting),
|
||||||
|
.outOther(outOther),
|
||||||
|
.passThrough (passThrough),
|
||||||
|
.sig (sig)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign sig_out = MyInterfaceInstance_mysig_out;
|
||||||
|
|
||||||
|
|
||||||
|
assign MyInterfaceInstance_setting = flip;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
module SubModule1(
|
||||||
|
input logic clk,
|
||||||
|
input logic rst,
|
||||||
|
input logic u_MyInterface_setting,
|
||||||
|
output logic [3:0] u_MyInterface_other_setting,
|
||||||
|
output logic [1:0] u_MyInterface_mysig_out,
|
||||||
|
output logic [21:0] outOther,
|
||||||
|
input logic [1:0] sig,
|
||||||
|
output logic [15:0] passThrough
|
||||||
|
);
|
||||||
|
|
||||||
|
always @(posedge clk or posedge rst)
|
||||||
|
if(rst)
|
||||||
|
u_MyInterface_mysig_out <= 0;
|
||||||
|
else begin
|
||||||
|
if(u_MyInterface_setting)
|
||||||
|
u_MyInterface_mysig_out <= sig;
|
||||||
|
else
|
||||||
|
u_MyInterface_mysig_out <= ~sig;
|
||||||
|
end
|
||||||
|
|
||||||
|
logic MyInterfaceInstanceInSub_setting;
|
||||||
|
logic [21:0] MyInterfaceInstanceInSub_other_setting;
|
||||||
|
logic [1:0] MyInterfaceInstanceInSub_mysig_out;
|
||||||
|
|
||||||
|
|
||||||
|
SubModule2 u_SubModule2 (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.u_MyInterfaceInSub2_setting(u_MyInterface_setting),
|
||||||
|
.u_MyInterfaceInSub2_mysig_out(u_MyInterface_mysig_out),
|
||||||
|
.u_MyInterfaceInSub2_other_setting(u_MyInterface_other_setting),
|
||||||
|
.u_MyInterfaceInSub3_setting(MyInterfaceInstanceInSub_setting),
|
||||||
|
.u_MyInterfaceInSub3_mysig_out(MyInterfaceInstanceInSub_mysig_out),
|
||||||
|
.u_MyInterfaceInSub3_other_setting(MyInterfaceInstanceInSub_other_setting),
|
||||||
|
.passThrough (passThrough)
|
||||||
|
);
|
||||||
|
assign outOther = MyInterfaceInstanceInSub_other_setting;
|
||||||
|
|
||||||
|
assign MyInterfaceInstanceInSub_setting = 0;
|
||||||
|
assign MyInterfaceInstanceInSub_mysig_out = sig;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module SubModule2(
|
||||||
|
|
||||||
|
input logic clk,
|
||||||
|
input logic rst,
|
||||||
|
input logic u_MyInterfaceInSub2_setting,
|
||||||
|
output logic [3:0] u_MyInterfaceInSub2_other_setting,
|
||||||
|
input logic [1:0] u_MyInterfaceInSub2_mysig_out,
|
||||||
|
input logic u_MyInterfaceInSub3_setting,
|
||||||
|
output logic [21:0] u_MyInterfaceInSub3_other_setting,
|
||||||
|
input logic [1:0] u_MyInterfaceInSub3_mysig_out,
|
||||||
|
output logic [15:0] passThrough
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
always @(u_MyInterfaceInSub3_mysig_out) begin
|
||||||
|
if (u_MyInterfaceInSub3_mysig_out == 2'b00)
|
||||||
|
u_MyInterfaceInSub3_other_setting[21:0] = 1000;
|
||||||
|
else if (u_MyInterfaceInSub3_mysig_out == 2'b01)
|
||||||
|
u_MyInterfaceInSub3_other_setting[21:0] = 2000;
|
||||||
|
else if (u_MyInterfaceInSub3_mysig_out == 2'b10)
|
||||||
|
u_MyInterfaceInSub3_other_setting[21:0] = 3000;
|
||||||
|
else
|
||||||
|
u_MyInterfaceInSub3_other_setting[21:0] = 4000;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign passThrough[7:0] = 124;
|
||||||
|
assign passThrough[15:8] = 200;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,57 @@
|
||||||
|
`timescale 1ns/10ps
|
||||||
|
|
||||||
|
module svinterface1_tb;
|
||||||
|
|
||||||
|
|
||||||
|
logic clk;
|
||||||
|
logic rst;
|
||||||
|
logic [21:0] outOther;
|
||||||
|
logic [1:0] sig;
|
||||||
|
logic [1:0] sig_out;
|
||||||
|
logic flip;
|
||||||
|
logic [15:0] passThrough;
|
||||||
|
integer outfile;
|
||||||
|
|
||||||
|
TopModule u_dut (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.outOther(outOther),
|
||||||
|
.sig(sig),
|
||||||
|
.flip(flip),
|
||||||
|
.passThrough(passThrough),
|
||||||
|
.sig_out(sig_out)
|
||||||
|
);
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
clk = 0;
|
||||||
|
while(1) begin
|
||||||
|
clk = ~clk;
|
||||||
|
#50;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
outfile = $fopen("output.txt");
|
||||||
|
rst = 1;
|
||||||
|
sig = 0;
|
||||||
|
flip = 0;
|
||||||
|
@(posedge clk);
|
||||||
|
#(2);
|
||||||
|
rst = 0;
|
||||||
|
@(posedge clk);
|
||||||
|
for(int j=0;j<2;j++) begin
|
||||||
|
for(int i=0;i<20;i++) begin
|
||||||
|
#(2);
|
||||||
|
flip = j;
|
||||||
|
sig = i;
|
||||||
|
@(posedge clk);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(negedge clk) begin
|
||||||
|
$fdisplay(outfile, "%d %d %d", outOther, sig_out, passThrough);
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,125 @@
|
||||||
|
|
||||||
|
|
||||||
|
module TopModule(
|
||||||
|
input logic clk,
|
||||||
|
input logic rst,
|
||||||
|
output logic [21:0] outOther,
|
||||||
|
input logic [1:0] sig,
|
||||||
|
input logic flip,
|
||||||
|
output logic [1:0] sig_out,
|
||||||
|
MyInterface.submodule1 interfaceInstanceAtTop,
|
||||||
|
output logic [15:0] passThrough);
|
||||||
|
|
||||||
|
MyInterface #(.WIDTH(4)) MyInterfaceInstance();
|
||||||
|
|
||||||
|
SubModule1 u_SubModule1 (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.u_MyInterface(MyInterfaceInstance),
|
||||||
|
.u_MyInterfaceFromTop(interfaceInstanceAtTop),
|
||||||
|
.outOther(outOther),
|
||||||
|
.sig (sig)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign sig_out = MyInterfaceInstance.mysig_out;
|
||||||
|
|
||||||
|
|
||||||
|
assign MyInterfaceInstance.setting = flip;
|
||||||
|
|
||||||
|
assign passThrough = MyInterfaceInstance.passThrough;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
interface MyInterface #(
|
||||||
|
parameter WIDTH = 3)(
|
||||||
|
);
|
||||||
|
|
||||||
|
logic setting;
|
||||||
|
logic [WIDTH-1:0] other_setting;
|
||||||
|
|
||||||
|
logic [1:0] mysig_out;
|
||||||
|
|
||||||
|
logic [15:0] passThrough;
|
||||||
|
|
||||||
|
modport submodule1 (
|
||||||
|
input setting,
|
||||||
|
output other_setting,
|
||||||
|
output mysig_out,
|
||||||
|
output passThrough
|
||||||
|
);
|
||||||
|
|
||||||
|
modport submodule2 (
|
||||||
|
input setting,
|
||||||
|
output other_setting,
|
||||||
|
input mysig_out,
|
||||||
|
output passThrough
|
||||||
|
);
|
||||||
|
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
|
||||||
|
module SubModule1(
|
||||||
|
input logic clk,
|
||||||
|
input logic rst,
|
||||||
|
MyInterface.submodule1 u_MyInterface,
|
||||||
|
MyInterface.submodule1 u_MyInterfaceFromTop,
|
||||||
|
input logic [1:0] sig,
|
||||||
|
output logic [21:0] outOther
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
always_ff @(posedge clk or posedge rst)
|
||||||
|
if(rst)
|
||||||
|
u_MyInterface.mysig_out <= 0;
|
||||||
|
else begin
|
||||||
|
if(u_MyInterface.setting)
|
||||||
|
u_MyInterface.mysig_out <= sig;
|
||||||
|
else
|
||||||
|
u_MyInterface.mysig_out <= ~sig;
|
||||||
|
end
|
||||||
|
|
||||||
|
MyInterface #(.WIDTH(22)) MyInterfaceInstanceInSub();
|
||||||
|
|
||||||
|
SubModule2 u_SubModule2 (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.u_MyInterfaceFromTopDown(u_MyInterfaceFromTop),
|
||||||
|
.u_MyInterfaceInSub2(u_MyInterface),
|
||||||
|
.u_MyInterfaceInSub3(MyInterfaceInstanceInSub)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign outOther = MyInterfaceInstanceInSub.other_setting;
|
||||||
|
|
||||||
|
assign MyInterfaceInstanceInSub.setting = 0;
|
||||||
|
assign MyInterfaceInstanceInSub.mysig_out = sig;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module SubModule2(
|
||||||
|
|
||||||
|
input logic clk,
|
||||||
|
input logic rst,
|
||||||
|
MyInterface.submodule2 u_MyInterfaceInSub2,
|
||||||
|
MyInterface.submodule1 u_MyInterfaceFromTopDown,
|
||||||
|
MyInterface.submodule2 u_MyInterfaceInSub3
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
assign u_MyInterfaceFromTopDown.mysig_out = u_MyInterfaceFromTop.setting ? 10 : 20;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
if (u_MyInterfaceInSub3.mysig_out == 2'b00)
|
||||||
|
u_MyInterfaceInSub3.other_setting[21:0] = 1000;
|
||||||
|
else if (u_MyInterfaceInSub3.mysig_out == 2'b01)
|
||||||
|
u_MyInterfaceInSub3.other_setting[21:0] = 2000;
|
||||||
|
else if (u_MyInterfaceInSub3.mysig_out == 2'b10)
|
||||||
|
u_MyInterfaceInSub3.other_setting[21:0] = 3000;
|
||||||
|
else
|
||||||
|
u_MyInterfaceInSub3.other_setting[21:0] = 4000;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign u_MyInterfaceInSub2.passThrough[7:0] = 124;
|
||||||
|
assign u_MyInterfaceInSub2.passThrough[15:8] = 200;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,120 @@
|
||||||
|
|
||||||
|
module TopModule(
|
||||||
|
input logic clk,
|
||||||
|
input logic rst,
|
||||||
|
input logic [1:0] sig,
|
||||||
|
input logic flip,
|
||||||
|
output logic [15:0] passThrough,
|
||||||
|
output logic [21:0] outOther,
|
||||||
|
input logic interfaceInstanceAtTop_setting,
|
||||||
|
output logic [2:0] interfaceInstanceAtTop_other_setting,
|
||||||
|
output logic [1:0] interfaceInstanceAtTop_mysig_out,
|
||||||
|
output logic [15:0] interfaceInstanceAtTop_passThrough,
|
||||||
|
output logic [1:0] sig_out);
|
||||||
|
|
||||||
|
|
||||||
|
logic MyInterfaceInstance_setting;
|
||||||
|
logic [3:0] MyInterfaceInstance_other_setting;
|
||||||
|
logic [1:0] MyInterfaceInstance_mysig_out;
|
||||||
|
|
||||||
|
SubModule1 u_SubModule1 (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.u_MyInterface_setting(MyInterfaceInstance_setting),
|
||||||
|
.u_MyInterface_mysig_out(MyInterfaceInstance_mysig_out),
|
||||||
|
.u_MyInterface_other_setting(MyInterfaceInstance_other_setting),
|
||||||
|
.u_MyInterfaceFromTop_setting(interfaceInstanceAtTop_setting),
|
||||||
|
.u_MyInterfaceFromTop_other_setting(interfaceInstanceAtTop_other_setting),
|
||||||
|
.u_MyInterfaceFromTop_mysig_out(interfaceInstanceAtTop_mysig_out),
|
||||||
|
.u_MyInterfaceFromTop_passThrough(interfaceInstanceAtTop_passThrough),
|
||||||
|
.outOther(outOther),
|
||||||
|
.passThrough (passThrough),
|
||||||
|
.sig (sig)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign sig_out = MyInterfaceInstance_mysig_out;
|
||||||
|
|
||||||
|
|
||||||
|
assign MyInterfaceInstance_setting = flip;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
module SubModule1(
|
||||||
|
input logic clk,
|
||||||
|
input logic rst,
|
||||||
|
input logic u_MyInterface_setting,
|
||||||
|
output logic [3:0] u_MyInterface_other_setting,
|
||||||
|
output logic [1:0] u_MyInterface_mysig_out,
|
||||||
|
output logic [21:0] outOther,
|
||||||
|
input logic [1:0] sig,
|
||||||
|
input logic u_MyInterfaceFromTop_setting,
|
||||||
|
output logic [2:0] u_MyInterfaceFromTop_other_setting,
|
||||||
|
output logic [1:0] u_MyInterfaceFromTop_mysig_out,
|
||||||
|
output logic [14:0] u_MyInterfaceFromTop_passThrough,
|
||||||
|
output logic [15:0] passThrough
|
||||||
|
);
|
||||||
|
|
||||||
|
always @(posedge clk or posedge rst)
|
||||||
|
if(rst)
|
||||||
|
u_MyInterface_mysig_out <= 0;
|
||||||
|
else begin
|
||||||
|
if(u_MyInterface_setting)
|
||||||
|
u_MyInterface_mysig_out <= sig;
|
||||||
|
else
|
||||||
|
u_MyInterface_mysig_out <= ~sig;
|
||||||
|
end
|
||||||
|
|
||||||
|
logic MyInterfaceInstanceInSub_setting;
|
||||||
|
logic [21:0] MyInterfaceInstanceInSub_other_setting;
|
||||||
|
logic [1:0] MyInterfaceInstanceInSub_mysig_out;
|
||||||
|
|
||||||
|
assign u_MyInterfaceFromTop_mysig_out = u_MyInterfaceFromTop_setting ? 10 : 20;
|
||||||
|
|
||||||
|
SubModule2 u_SubModule2 (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.u_MyInterfaceInSub2_setting(u_MyInterface_setting),
|
||||||
|
.u_MyInterfaceInSub2_mysig_out(u_MyInterface_mysig_out),
|
||||||
|
.u_MyInterfaceInSub2_other_setting(u_MyInterface_other_setting),
|
||||||
|
.u_MyInterfaceInSub3_setting(MyInterfaceInstanceInSub_setting),
|
||||||
|
.u_MyInterfaceInSub3_mysig_out(MyInterfaceInstanceInSub_mysig_out),
|
||||||
|
.u_MyInterfaceInSub3_other_setting(MyInterfaceInstanceInSub_other_setting),
|
||||||
|
.passThrough (passThrough)
|
||||||
|
);
|
||||||
|
assign outOther = MyInterfaceInstanceInSub_other_setting;
|
||||||
|
|
||||||
|
assign MyInterfaceInstanceInSub_setting = 0;
|
||||||
|
assign MyInterfaceInstanceInSub_mysig_out = sig;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module SubModule2(
|
||||||
|
|
||||||
|
input logic clk,
|
||||||
|
input logic rst,
|
||||||
|
input logic u_MyInterfaceInSub2_setting,
|
||||||
|
output logic [3:0] u_MyInterfaceInSub2_other_setting,
|
||||||
|
input logic [1:0] u_MyInterfaceInSub2_mysig_out,
|
||||||
|
input logic u_MyInterfaceInSub3_setting,
|
||||||
|
output logic [21:0] u_MyInterfaceInSub3_other_setting,
|
||||||
|
input logic [1:0] u_MyInterfaceInSub3_mysig_out,
|
||||||
|
output logic [15:0] passThrough
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
always @(u_MyInterfaceInSub3_mysig_out) begin
|
||||||
|
if (u_MyInterfaceInSub3_mysig_out == 2'b00)
|
||||||
|
u_MyInterfaceInSub3_other_setting[21:0] = 1000;
|
||||||
|
else if (u_MyInterfaceInSub3_mysig_out == 2'b01)
|
||||||
|
u_MyInterfaceInSub3_other_setting[21:0] = 2000;
|
||||||
|
else if (u_MyInterfaceInSub3_mysig_out == 2'b10)
|
||||||
|
u_MyInterfaceInSub3_other_setting[21:0] = 3000;
|
||||||
|
else
|
||||||
|
u_MyInterfaceInSub3_other_setting[21:0] = 4000;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign passThrough[7:0] = 124;
|
||||||
|
assign passThrough[15:8] = 200;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,68 @@
|
||||||
|
`timescale 1ns/10ps
|
||||||
|
|
||||||
|
module svinterface_at_top_tb;
|
||||||
|
|
||||||
|
|
||||||
|
logic clk;
|
||||||
|
logic rst;
|
||||||
|
logic [21:0] outOther;
|
||||||
|
logic [1:0] sig;
|
||||||
|
logic [1:0] sig_out;
|
||||||
|
logic flip;
|
||||||
|
logic [15:0] passThrough;
|
||||||
|
integer outfile;
|
||||||
|
|
||||||
|
logic interfaceInstanceAtTop_setting;
|
||||||
|
logic [2:0] interfaceInstanceAtTop_other_setting;
|
||||||
|
logic [1:0] interfaceInstanceAtTop_mysig_out;
|
||||||
|
logic [15:0] interfaceInstanceAtTop_passThrough;
|
||||||
|
|
||||||
|
|
||||||
|
TopModule u_dut (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.outOther(outOther),
|
||||||
|
.sig(sig),
|
||||||
|
.flip(flip),
|
||||||
|
.passThrough(passThrough),
|
||||||
|
.interfaceInstanceAtTop_setting(interfaceInstanceAtTop_setting),
|
||||||
|
.interfaceInstanceAtTop_other_setting(interfaceInstanceAtTop_other_setting),
|
||||||
|
.interfaceInstanceAtTop_mysig_out(interfaceInstanceAtTop_mysig_out),
|
||||||
|
.interfaceInstanceAtTop_passThrough(interfaceInstanceAtTop_passThrough),
|
||||||
|
.sig_out(sig_out)
|
||||||
|
);
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
clk = 0;
|
||||||
|
while(1) begin
|
||||||
|
clk = ~clk;
|
||||||
|
#50;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
outfile = $fopen("output.txt");
|
||||||
|
rst = 1;
|
||||||
|
interfaceInstanceAtTop_setting = 0;
|
||||||
|
sig = 0;
|
||||||
|
flip = 0;
|
||||||
|
@(posedge clk);
|
||||||
|
#(2);
|
||||||
|
rst = 0;
|
||||||
|
@(posedge clk);
|
||||||
|
for(int j=0;j<2;j++) begin
|
||||||
|
for(int i=0;i<20;i++) begin
|
||||||
|
#(2);
|
||||||
|
flip = j;
|
||||||
|
sig = i;
|
||||||
|
@(posedge clk);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(negedge clk) begin
|
||||||
|
$fdisplay(outfile, "%d %d %d %d", outOther, sig_out, passThrough, interfaceInstanceAtTop_mysig_out);
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,68 @@
|
||||||
|
`timescale 1ns/10ps
|
||||||
|
|
||||||
|
module svinterface_at_top_tb_wrapper;
|
||||||
|
|
||||||
|
|
||||||
|
logic clk;
|
||||||
|
logic rst;
|
||||||
|
logic [21:0] outOther;
|
||||||
|
logic [1:0] sig;
|
||||||
|
logic [1:0] sig_out;
|
||||||
|
logic flip;
|
||||||
|
logic [15:0] passThrough;
|
||||||
|
integer outfile;
|
||||||
|
|
||||||
|
logic interfaceInstanceAtTop_setting;
|
||||||
|
logic [2:0] interfaceInstanceAtTop_other_setting;
|
||||||
|
logic [1:0] interfaceInstanceAtTop_mysig_out;
|
||||||
|
logic [15:0] interfaceInstanceAtTop_passThrough;
|
||||||
|
|
||||||
|
|
||||||
|
TopModule u_dut (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.outOther(outOther),
|
||||||
|
.sig(sig),
|
||||||
|
.flip(flip),
|
||||||
|
.passThrough(passThrough),
|
||||||
|
.\interfaceInstanceAtTop.setting (interfaceInstanceAtTop_setting),
|
||||||
|
.\interfaceInstanceAtTop.other_setting (interfaceInstanceAtTop_other_setting),
|
||||||
|
.\interfaceInstanceAtTop.mysig_out (interfaceInstanceAtTop_mysig_out),
|
||||||
|
.\interfaceInstanceAtTop.passThrough (interfaceInstanceAtTop_passThrough),
|
||||||
|
.sig_out(sig_out)
|
||||||
|
);
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
clk = 0;
|
||||||
|
while(1) begin
|
||||||
|
clk = ~clk;
|
||||||
|
#50;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
outfile = $fopen("output.txt");
|
||||||
|
rst = 1;
|
||||||
|
sig = 0;
|
||||||
|
interfaceInstanceAtTop_setting = 0;
|
||||||
|
flip = 0;
|
||||||
|
@(posedge clk);
|
||||||
|
#(2);
|
||||||
|
rst = 0;
|
||||||
|
@(posedge clk);
|
||||||
|
for(int j=0;j<2;j++) begin
|
||||||
|
for(int i=0;i<20;i++) begin
|
||||||
|
#(2);
|
||||||
|
flip = j;
|
||||||
|
sig = i;
|
||||||
|
@(posedge clk);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(negedge clk) begin
|
||||||
|
$fdisplay(outfile, "%d %d %d %d", outOther, sig_out, passThrough, interfaceInstanceAtTop_mysig_out);
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,33 @@
|
||||||
|
`timescale 1ns/10ps
|
||||||
|
|
||||||
|
module svinterface_at_top_wrapper(
|
||||||
|
input logic clk,
|
||||||
|
input logic rst,
|
||||||
|
output logic [21:0] outOther,
|
||||||
|
input logic [1:0] sig,
|
||||||
|
output logic [1:0] sig_out,
|
||||||
|
input logic flip,
|
||||||
|
output logic [15:0] passThrough,
|
||||||
|
|
||||||
|
input logic interfaceInstanceAtTop_setting,
|
||||||
|
output logic [2:0] interfaceInstanceAtTop_other_setting,
|
||||||
|
output logic [1:0] interfaceInstanceAtTop_mysig_out,
|
||||||
|
output logic [15:0] interfaceInstanceAtTop_passThrough,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
TopModule u_dut (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.outOther(outOther),
|
||||||
|
.sig(sig),
|
||||||
|
.flip(flip),
|
||||||
|
.passThrough(passThrough),
|
||||||
|
.\interfaceInstanceAtTop.setting(interfaceInstanceAtTop_setting),
|
||||||
|
.\interfaceInstanceAtTop.other_setting(interfaceInstanceAtTop_other_setting),
|
||||||
|
.\interfaceInstanceAtTop.mysig_out(interfaceInstanceAtTop_mysig_out),
|
||||||
|
.\interfaceInstanceAtTop.passThrough(interfaceInstanceAtTop_passThrough),
|
||||||
|
.sig_out(sig_out)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
Loading…
Reference in New Issue