aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--backends/verilog/verilog_backend.cc8
-rw-r--r--passes/opt/pmux2shiftx.cc23
-rw-r--r--passes/techmap/attrmap.cc4
-rw-r--r--tests/various/pmux2shiftx.ys4
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