diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 0e28dbca2..cb54ffa58 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 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 { + score = max(score, find_top_mod_score(design, instModule, db) + 1); + } + } db[module] = score; } return db.at(module); diff --git a/tests/various/hierarchy.sh b/tests/various/hierarchy.sh new file mode 100644 index 000000000..d33a247be --- /dev/null +++ b/tests/various/hierarchy.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# Simple test of hierarchy -auto-top. + +set -e + +echo -n " TOP first - " +../../yosys -s - <<- EOY | grep "Automatically selected TOP as design top module" + read_verilog << EOV + module TOP(a, y); + input a; + output [31:0] y; + + aoi12 p [31:0] (a, y); + endmodule + + module aoi12(a, y); + input a; + output y; + assign y = ~a; + endmodule + EOV + hierarchy -auto-top +EOY + +echo -n " TOP last - " +../../yosys -s - <<- EOY | grep "Automatically selected TOP as design top module" + read_verilog << EOV + module aoi12(a, y); + input a; + output y; + assign y = ~a; + endmodule + + module TOP(a, y); + input a; + output [31:0] y; + + aoi12 foo (a, y); + endmodule + EOV + hierarchy -auto-top +EOY + +echo -n " no explicit top - " +../../yosys -s - <<- EOY | grep "Automatically selected noTop as design top module." + read_verilog << EOV + module aoi12(a, y); + input a; + output y; + assign y = ~a; + endmodule + + module noTop(a, y); + input a; + output [31:0] y; + endmodule + EOV + hierarchy -auto-top +EOY diff --git a/tests/various/run-test.sh b/tests/various/run-test.sh index 67e1beb23..d49553ede 100755 --- a/tests/various/run-test.sh +++ b/tests/various/run-test.sh @@ -1,6 +1,14 @@ -#!/bin/bash +#!/usr/bin/env bash set -e for x in *.ys; do echo "Running $x.." ../../yosys -ql ${x%.ys}.log $x done +# Run any .sh files in this directory (with the exception of the file - run-test.sh +shell_tests=$(echo *.sh | sed -e 's/run-test.sh//') +if [ "$shell_tests" ]; then + for s in $shell_tests; do + echo "Running $s.." + bash $s + done +fi