Fix _TECHMAP_REMOVEINIT_ handling.
authorMarcin Kościelnicki <marcin@symbioticeda.com>
Fri, 27 Sep 2019 09:03:04 +0000 (11:03 +0200)
committerMarcin Kościelnicki <koriakin@0x04.net>
Fri, 27 Sep 2019 16:34:12 +0000 (18:34 +0200)
Previously, this wire was handled in the code that populated the "do or
do not" techmap cache, resulting in init value removal being performed
only for the first use of a given template.

Fixes the problem identified in #1396.

passes/techmap/techmap.cc
tests/techmap/wireinit.ys

index 1d0362ad67b3e24eeece7d0942b22cbcce72a769..08a1af2d553188365e72bf11170b14b1fd54440e 100644 (file)
@@ -935,19 +935,6 @@ struct TechmapWorker
                                                        for (auto &it2 : it.second)
                                                                if (!it2.value.is_fully_const())
                                                                        log_error("Techmap yielded config wire %s with non-const value %s.\n", RTLIL::id2cstr(it2.wire->name), log_signal(it2.value));
-                                               if (it.first.substr(0, 20) == "_TECHMAP_REMOVEINIT_" && techmap_do_cache[tpl]) {
-                                                       for (auto &it2 : it.second) {
-                                                               auto val = it2.value.as_const();
-                                                               auto wirename = RTLIL::escape_id(it.first.substr(20, it.first.size() - 20 - 1));
-                                                               auto it = cell->connections().find(wirename);
-                                                               if (it != cell->connections().end()) {
-                                                                       auto sig = sigmap(it->second);
-                                                                       for (int i = 0; i < sig.size(); i++)
-                                                                               if (val[i] == State::S1)
-                                                                                       remove_init_bits.insert(sig[i]);
-                                                               }
-                                                       }
-                                               }
                                                techmap_wire_names.erase(it.first);
                                        }
 
@@ -973,6 +960,23 @@ struct TechmapWorker
                                        mkdebug.off();
                                }
 
+                               TechmapWires twd = techmap_find_special_wires(tpl);
+                               for (auto &it : twd) {
+                                       if (it.first.substr(0, 20) == "_TECHMAP_REMOVEINIT_") {
+                                               for (auto &it2 : it.second) {
+                                                       auto val = it2.value.as_const();
+                                                       auto wirename = RTLIL::escape_id(it.first.substr(20, it.first.size() - 20 - 1));
+                                                       auto it = cell->connections().find(wirename);
+                                                       if (it != cell->connections().end()) {
+                                                               auto sig = sigmap(it->second);
+                                                               for (int i = 0; i < sig.size(); i++)
+                                                                       if (val[i] == State::S1)
+                                                                               remove_init_bits.insert(sig[i]);
+                                                       }
+                                               }
+                                       }
+                               }
+
                                if (extern_mode && !in_recursion)
                                {
                                        std::string m_name = stringf("$extern:%s", log_id(tpl));
index 1396839fec6fdb327d306c1ae6420bab70688080..89afaafb5f0c9ff164067d50818ab3e1983d96ab 100644 (file)
@@ -46,11 +46,13 @@ input clk;
 input d;
 output reg q0 = 0;
 output reg q1 = 1;
+output reg qq0 = 0;
 output reg qx;
 
 always @(posedge clk) begin
        q0 <= d;
        q1 <= d;
+       qq0 <= q0;
        qx <= d;
 end
 endmodule
@@ -64,16 +66,20 @@ simplemap
 techmap -map %map
 clean
 # Make sure the parameter was used properly.
-select -assert-count 2 top/t:ffbb
+select -assert-count 3 top/t:ffbb
 select -set ff0 top/w:q0 %ci t:ffbb %i
+select -set ffq0 top/w:qq0 %ci t:ffbb %i
 select -set ffx top/w:qx %ci t:ffbb %i
 select -assert-count 1 @ff0
+select -assert-count 1 @ffq0
 select -assert-count 1 @ffx
 select -assert-count 1 @ff0 r:INIT=1'b0 %i
+select -assert-count 1 @ffq0 r:INIT=1'b0 %i
 select -assert-count 1 @ffx r:INIT=1'bx %i
 select -assert-count 0 top/w:q1 %ci t:ffbb %i
 # Make sure the init values are dropped from the wires iff mapping was performed.
 select -assert-count 0 top/w:q0 a:init %i
+select -assert-count 0 top/w:qq0 a:init %i
 select -assert-count 1 top/w:q1 a:init=1'b1 %i
 select -assert-count 0 top/w:qx a:init %i
 
@@ -84,15 +90,19 @@ simplemap
 techmap -map %map_noremove
 clean
 # Make sure the parameter was used properly.
-select -assert-count 2 top/t:ffbb
+select -assert-count 3 top/t:ffbb
 select -set ff0 top/w:q0 %ci t:ffbb %i
+select -set ffq0 top/w:qq0 %ci t:ffbb %i
 select -set ffx top/w:qx %ci t:ffbb %i
 select -assert-count 1 @ff0
+select -assert-count 1 @ffq0
 select -assert-count 1 @ffx
 select -assert-count 1 @ff0 r:INIT=1'b0 %i
+select -assert-count 1 @ffq0 r:INIT=1'b0 %i
 select -assert-count 1 @ffx r:INIT=1'bx %i
 select -assert-count 0 top/w:q1 %ci t:ffbb %i
 # Make sure the init values are not dropped from the wires.
 select -assert-count 1 top/w:q0 a:init=1'b0 %i
+select -assert-count 1 top/w:qq0 a:init=1'b0 %i
 select -assert-count 1 top/w:q1 a:init=1'b1 %i
 select -assert-count 0 top/w:qx a:init %i