diff options
-rw-r--r-- | backends/verilog/verilog_backend.cc | 8 | ||||
-rw-r--r-- | passes/opt/pmux2shiftx.cc | 23 | ||||
-rw-r--r-- | passes/techmap/attrmap.cc | 4 | ||||
-rw-r--r-- | tests/various/pmux2shiftx.ys | 4 |
4 files changed, 35 insertions, 4 deletions
diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 855409d0b..9967482d6 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -187,6 +187,10 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o { if (width < 0) width = data.bits.size() - offset; + if (width == 0) { + f << "\"\""; + return; + } if (nostr) goto dump_hex; if ((data.flags & RTLIL::CONST_FLAG_STRING) == 0 || width != (int)data.bits.size()) { @@ -340,6 +344,10 @@ void dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool no_decima void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig) { + if (GetSize(sig) == 0) { + f << "\"\""; + return; + } if (sig.is_chunk()) { dump_sigchunk(f, sig.as_chunk()); } else { diff --git a/passes/opt/pmux2shiftx.cc b/passes/opt/pmux2shiftx.cc index 5f897b131..29870f510 100644 --- a/passes/opt/pmux2shiftx.cc +++ b/passes/opt/pmux2shiftx.cc @@ -369,6 +369,7 @@ struct Pmux2ShiftxPass : public Pass { dict<SigSpec, pool<int>> seldb; + SigSpec A = cell->getPort("\\A"); SigSpec B = cell->getPort("\\B"); SigSpec S = sigmap(cell->getPort("\\S")); for (int i = 0; i < GetSize(S); i++) @@ -419,6 +420,8 @@ struct Pmux2ShiftxPass : public Pass { choices[val] = i; } + bool full_pmux = GetSize(choices) == GetSize(S); + // TBD: also find choices that are using signals that are subsets of the bits in "sig" if (!verbose) @@ -634,7 +637,21 @@ struct Pmux2ShiftxPass : public Pass { log(" range density: %d%%\n", range_density); log(" absolute density: %d%%\n", absolute_density); - bool full_case = (min_choice == 0) && (max_choice == (1 << GetSize(sig))-1) && (max_choice+1 == GetSize(choices)); + if (full_pmux) { + int full_density = 100*GetSize(choices) / (1 << GetSize(sig)); + log(" full density: %d%%\n", full_density); + if (full_density < min_density) { + full_pmux = false; + } else { + min_choice = 0; + max_choice = (1 << GetSize(sig))-1; + log(" update to full case.\n"); + log(" new min choice: %d\n", min_choice); + log(" new max choice: %d\n", max_choice); + } + } + + bool full_case = (min_choice == 0) && (max_choice == (1 << GetSize(sig))-1) && (full_pmux || max_choice+1 == GetSize(choices)); log(" full case: %s\n", full_case ? "true" : "false"); // check density percentages @@ -677,6 +694,10 @@ struct Pmux2ShiftxPass : public Pass { // create data signal SigSpec data(State::Sx, (max_choice+1)*extwidth); + if (full_pmux) { + for (int i = 0; i <= max_choice; i++) + data.replace(i*extwidth, A); + } for (auto &it : perm_choices) { int position = it.first.as_int()*extwidth; int data_index = it.second; diff --git a/passes/techmap/attrmap.cc b/passes/techmap/attrmap.cc index 0b5576b06..aa48e1125 100644 --- a/passes/techmap/attrmap.cc +++ b/passes/techmap/attrmap.cc @@ -111,9 +111,10 @@ struct AttrmapMap : AttrmapAction { }; struct AttrmapRemove : AttrmapAction { + bool has_value; string name, value; bool apply(IdString &id, Const &val) YS_OVERRIDE { - return !(match_name(name, id) && match_value(value, val)); + return !(match_name(name, id) && (!has_value || match_value(value, val))); } }; @@ -235,6 +236,7 @@ struct AttrmapPass : public Pass { } auto action = new AttrmapRemove; action->name = arg1; + action->has_value = (p != string::npos); action->value = val1; actions.push_back(std::unique_ptr<AttrmapAction>(action)); continue; diff --git a/tests/various/pmux2shiftx.ys b/tests/various/pmux2shiftx.ys index 6bb9626eb..deb134083 100644 --- a/tests/various/pmux2shiftx.ys +++ b/tests/various/pmux2shiftx.ys @@ -9,8 +9,8 @@ opt stat # show -width select -assert-count 1 t:$sub -select -assert-count 2 t:$mux -select -assert-count 2 t:$shift +select -assert-count 1 t:$mux +select -assert-count 1 t:$shift select -assert-count 3 t:$shiftx design -stash gate |