diff options
Diffstat (limited to 'passes')
-rw-r--r-- | passes/cmds/design.cc | 24 | ||||
-rw-r--r-- | passes/opt/opt_expr.cc | 19 |
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); |