aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--backends/firrtl/firrtl.cc10
-rw-r--r--passes/opt/wreduce.cc10
-rw-r--r--techlibs/common/prep.cc6
3 files changed, 20 insertions, 6 deletions
diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc
index fe6bdb8f6..1c7a7351f 100644
--- a/backends/firrtl/firrtl.cc
+++ b/backends/firrtl/firrtl.cc
@@ -146,7 +146,7 @@ struct FirrtlWorker
if (!mask.is_fully_def())
this->ena = SigSpec(RTLIL::Const(1));
}
- string gen_read(const char * /* indent */) {
+ string gen_read(const char * /* indent */) {
log_error("gen_read called on write_port: %s\n", name.c_str());
return stringf("gen_read called on write_port: %s\n", name.c_str());
}
@@ -449,8 +449,10 @@ struct FirrtlWorker
string primop;
bool always_uint = false;
if (cell->type == "$not") primop = "not";
- else if (cell->type == "$neg") primop = "neg";
- else if (cell->type == "$logic_not") {
+ else if (cell->type == "$neg") {
+ primop = "neg";
+ is_signed = true; // Result of "neg" is signed (an SInt).
+ } else if (cell->type == "$logic_not") {
primop = "eq";
a_expr = stringf("%s, UInt(0)", a_expr.c_str());
}
@@ -562,6 +564,7 @@ struct FirrtlWorker
auto b_sig = cell->getPort("\\B");
if (b_sig.is_fully_const()) {
primop = "shl";
+ b_expr = std::to_string(b_sig.as_int());
} else {
primop = "dshl";
// Convert from FIRRTL left shift semantics.
@@ -575,6 +578,7 @@ struct FirrtlWorker
auto b_sig = cell->getPort("\\B");
if (b_sig.is_fully_const()) {
primop = "shr";
+ b_expr = std::to_string(b_sig.as_int());
} else {
primop = "dshr";
}
diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc
index 58c6e4b4b..1fbc41082 100644
--- a/passes/opt/wreduce.cc
+++ b/passes/opt/wreduce.cc
@@ -29,6 +29,7 @@ PRIVATE_NAMESPACE_BEGIN
struct WreduceConfig
{
pool<IdString> supported_cell_types;
+ bool keepdc = false;
WreduceConfig()
{
@@ -82,7 +83,7 @@ struct WreduceWorker
SigBit ref = sig_a[i];
for (int k = 0; k < GetSize(sig_s); k++) {
- if (ref != Sx && sig_b[k*GetSize(sig_a) + i] != Sx && ref != sig_b[k*GetSize(sig_a) + i])
+ if ((config->keepdc || (ref != Sx && sig_b[k*GetSize(sig_a) + i] != Sx)) && ref != sig_b[k*GetSize(sig_a) + i])
goto no_match_ab;
if (sig_b[k*GetSize(sig_a) + i] != Sx)
ref = sig_b[k*GetSize(sig_a) + i];
@@ -495,6 +496,9 @@ struct WreducePass : public Pass {
log(" Do not change the width of memory address ports. Use this options in\n");
log(" flows that use the 'memory_memx' pass.\n");
log("\n");
+ log(" -keepdc\n");
+ log(" Do not optimize explicit don't-care values.\n");
+ log("\n");
}
void execute(std::vector<std::string> args, Design *design) YS_OVERRIDE
{
@@ -509,6 +513,10 @@ struct WreducePass : public Pass {
opt_memx = true;
continue;
}
+ if (args[argidx] == "-keepdc") {
+ config.keepdc = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
diff --git a/techlibs/common/prep.cc b/techlibs/common/prep.cc
index 86fb4d6c6..cdd21c3b3 100644
--- a/techlibs/common/prep.cc
+++ b/techlibs/common/prep.cc
@@ -195,9 +195,11 @@ struct PrepPass : public ScriptPass
run(nokeepdc ? "opt" : "opt -keepdc");
if (!ifxmode) {
if (help_mode)
- run("wreduce [-memx]");
- else
+ run("wreduce -keepdc [-memx]");
+ else if (nokeepdc)
run(memxmode ? "wreduce -memx" : "wreduce");
+ else
+ run(memxmode ? "wreduce -keepdc -memx" : "wreduce -keepdc");
}
if (!nomemmode) {
run(string("memory_dff") + (help_mode ? " [-nordff]" : nordff ? " -nordff" : ""));