Fix _TECHMAP_REMOVEINIT_ handling.

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.
This commit is contained in:
Marcin Kościelnicki 2019-09-27 11:03:04 +02:00 committed by Marcin Kościelnicki
parent 4b15cf5f76
commit fd0e3a2c43
2 changed files with 29 additions and 15 deletions

View 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));

View 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