hierarchy: Correct handling of wildcard port connections with default values
authorDavid Shah <dave@ds0.me>
Fri, 22 Nov 2019 09:21:35 +0000 (09:21 +0000)
committerDavid Shah <dave@ds0.me>
Sun, 2 Feb 2020 16:12:33 +0000 (16:12 +0000)
Signed-off-by: David Shah <dave@ds0.me>
passes/hierarchy/hierarchy.cc
tests/various/sv_implicit_ports.sh

index 0704c26512efbae2c18c58a4fba14946ba62ca76..c298a660087565471a3a19a53c14f74de565a5da 100644 (file)
@@ -983,6 +983,15 @@ struct HierarchyPass : public Pass {
                        }
                }
 
+               // Determine default values
+               dict<IdString, dict<IdString, Const>> defaults_db;
+               if (!nodefaults)
+               {
+                       for (auto module : design->modules())
+                               for (auto wire : module->wires())
+                                       if (wire->port_input && wire->attributes.count("\\defaultvalue"))
+                                               defaults_db[module->name][wire->name] = wire->attributes.at("\\defaultvalue");
+               }
                // Process SV implicit port connections
                std::set<Module*> blackbox_derivatives;
                std::vector<Module*> design_modules = design->modules();
@@ -1019,6 +1028,11 @@ struct HierarchyPass : public Pass {
                                                continue;
                                        // Make sure a wire of correct name exists in the parent
                                        Wire* parent_wire = find_implicit_port_wire(module, cell, wire->name.str());
+
+                                       // Missing wires are OK when a default value is set
+                                       if (!nodefaults && parent_wire == nullptr && defaults_db.count(cell->type) && defaults_db.at(cell->type).count(wire->name))
+                                               continue;
+
                                        if (parent_wire == nullptr)
                                                log_error("No matching wire for implicit port connection `%s' of cell %s.%s (%s).\n",
                                                                RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
@@ -1034,13 +1048,6 @@ struct HierarchyPass : public Pass {
 
                if (!nodefaults)
                {
-                       dict<IdString, dict<IdString, Const>> defaults_db;
-
-                       for (auto module : design->modules())
-                               for (auto wire : module->wires())
-                                       if (wire->port_input && wire->attributes.count("\\defaultvalue"))
-                                               defaults_db[module->name][wire->name] = wire->attributes.at("\\defaultvalue");
-
                        for (auto module : design->modules())
                                for (auto cell : module->cells())
                                {
index 13d39cf8bf98e37615d6883e608ccdc5d8d54c74..2faac2e85a93809efe53620f4637aebcf901d47d 100755 (executable)
@@ -54,3 +54,14 @@ module top(input [7:0] a, output [7:0] q);
 endmodule
 EOT
 ) 2>&1 | grep -F "ERROR: Width mismatch between wire (7 bits) and port (8 bits) for implicit port connection \`b' of cell top.add_i (add)." > /dev/null
+
+# Defaults
+../../yosys -f "verilog -sv" -qp "prep -flatten -top top; select -assert-count 1 t:\$add" - <<EOT
+module add(input [7:0] a = 8'd00, input [7:0] b = 8'd01, output [7:0] q);
+assign q = a + b;
+endmodule
+
+module top(input [7:0] a, output [7:0] q);
+       add add_i(.*);
+endmodule
+EOT