aboutsummaryrefslogtreecommitdiffstats
path: root/passes
diff options
context:
space:
mode:
Diffstat (limited to 'passes')
-rw-r--r--passes/cmds/design.cc24
-rw-r--r--passes/opt/opt_expr.cc19
2 files changed, 39 insertions, 4 deletions
diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc
index 4612760cc..cfe97067d 100644
--- a/passes/cmds/design.cc
+++ b/passes/cmds/design.cc
@@ -99,6 +99,11 @@ struct DesignPass : public Pass {
log("The Verilog front-end remembers defined macros and top-level declarations\n");
log("between calls to 'read_verilog'. This command resets this memory.\n");
log("\n");
+ log(" design -delete <name>\n");
+ log("\n");
+ log("Delete the design previously saved under the given name.\n");
+ log("\n");
+
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
@@ -110,7 +115,7 @@ struct DesignPass : public Pass {
bool pop_mode = false;
bool import_mode = false;
RTLIL::Design *copy_from_design = NULL, *copy_to_design = NULL;
- std::string save_name, load_name, as_name;
+ std::string save_name, load_name, as_name, delete_name;
std::vector<RTLIL::Module*> copy_src_modules;
size_t argidx;
@@ -190,6 +195,13 @@ struct DesignPass : public Pass {
as_name = args[++argidx];
continue;
}
+ if (!got_mode && args[argidx] == "-delete" && argidx+1 < args.size()) {
+ got_mode = true;
+ delete_name = args[++argidx];
+ if (saved_designs.count(delete_name) == 0)
+ log_cmd_error("No saved design '%s' found!\n", delete_name.c_str());
+ continue;
+ }
break;
}
@@ -340,7 +352,7 @@ struct DesignPass : public Pass {
if (reset_mode || !load_name.empty() || push_mode || pop_mode)
{
- for (auto mod : design->modules())
+ for (auto mod : design->modules().to_vector())
design->remove(mod);
design->selection_stack.clear();
@@ -379,6 +391,14 @@ struct DesignPass : public Pass {
pushed_designs.pop_back();
}
}
+
+ if (!delete_name.empty())
+ {
+ auto it = saved_designs.find(delete_name);
+ log_assert(it != saved_designs.end());
+ delete it->second;
+ saved_designs.erase(it);
+ }
}
} DesignPass;
diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc
index 3229dd1b2..2b35ace5e 100644
--- a/passes/opt/opt_expr.cc
+++ b/passes/opt/opt_expr.cc
@@ -1135,9 +1135,24 @@ skip_fine_alu:
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B');
if (cell->type == ID($alu)) {
+ bool a_signed = cell->parameters[ID::A_SIGNED].as_bool();
+ bool b_signed = cell->parameters[ID::B_SIGNED].as_bool();
+ bool is_signed = a_signed && b_signed;
+ RTLIL::SigBit sig_ci = assign_map(cell->getPort(ID::CI));
int y_width = GetSize(cell->getPort(ID::Y));
- module->connect(cell->getPort(ID::X), RTLIL::Const(State::S0, y_width));
- module->connect(cell->getPort(ID::CO), RTLIL::Const(State::S0, y_width));
+ if (sig_ci == State::S1) {
+ /* sub, b is 0 */
+ RTLIL::SigSpec a = cell->getPort(ID::A);
+ a.extend_u0(y_width, is_signed);
+ module->connect(cell->getPort(ID::X), module->Not(NEW_ID, a));
+ module->connect(cell->getPort(ID::CO), RTLIL::Const(State::S1, y_width));
+ } else {
+ /* add */
+ RTLIL::SigSpec ab = cell->getPort(identity_wrt_a ? ID::A : ID::B);
+ ab.extend_u0(y_width, is_signed);
+ module->connect(cell->getPort(ID::X), ab);
+ module->connect(cell->getPort(ID::CO), RTLIL::Const(State::S0, y_width));
+ }
cell->unsetPort(ID::BI);
cell->unsetPort(ID::CI);
cell->unsetPort(ID::X);