glift: Add replacement scoring and area minimization option.

This commit is contained in:
Alberto Gonzalez 2020-04-23 06:41:58 +00:00
parent c36440a7ee
commit 72cebef279
No known key found for this signature in database
GPG Key ID: 8395A8BA109708B2
1 changed files with 56 additions and 3 deletions

View File

@ -27,10 +27,11 @@ PRIVATE_NAMESPACE_BEGIN
struct GliftPass : public Pass {
private:
bool opt_create, opt_sketchify, opt_taintconstants, opt_keepoutputs;
bool opt_create, opt_sketchify, opt_taintconstants, opt_keepoutputs, opt_nomodeloptimize;
std::vector<std::string> args;
std::vector<std::string>::size_type argidx;
std::vector<RTLIL::Wire *> new_taint_outputs;
std::vector<RTLIL::SigSpec> meta_mux_selects;
RTLIL::Module *module;
void parse_args() {
@ -51,6 +52,10 @@ struct GliftPass : public Pass {
opt_keepoutputs = true;
continue;
}
if (args[argidx] == "-no-model-optimize") {
opt_nomodeloptimize = true;
continue;
}
break;
}
if(!opt_create && !opt_sketchify) log_cmd_error("One of `-create` or `-sketchify` must be specified.\n");
@ -116,6 +121,22 @@ struct GliftPass : public Pass {
module->addOr(cell->name.str() + "_t_4_1", port_a_taint, port_b_taint, port_y_taint, false, cell->get_src_attribute());
}
RTLIL::SigSpec score_metamux_select(const RTLIL::SigSpec &metamux_select) {
log_assert(metamux_select.is_wire());
log_assert(metamux_select.as_wire()->width == 2);
RTLIL::Const precise_y_cost(5); //5 AND/OR gates
RTLIL::Const imprecise_1_y_cost(2);
RTLIL::Const imprecise_2_y_cost(2);
RTLIL::Const imprecise_3_y_cost(1);
RTLIL::SigSpec meta_mux1 = module->Pmux(metamux_select.as_wire()->name.str() + "_mux1", precise_y_cost, imprecise_1_y_cost, metamux_select[1], metamux_select.as_wire()->get_src_attribute());
RTLIL::SigSpec meta_mux2 = module->Pmux(metamux_select.as_wire()->name.str() + "_mux2", imprecise_2_y_cost, imprecise_3_y_cost, metamux_select[1], metamux_select.as_wire()->get_src_attribute());
RTLIL::SigSpec ret = module->Pmux(metamux_select.as_wire()->name.str() + "_mux3", meta_mux1, meta_mux2, metamux_select[0], metamux_select.as_wire()->get_src_attribute());
return ret;
}
void create_glift_logic() {
std::vector<RTLIL::SigSig> connections(module->connections());
std::vector<RTLIL::SigSig> new_connections;
@ -149,8 +170,9 @@ struct GliftPass : public Pass {
add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], imprecise_3_y);
RTLIL::SigSpec meta_mux_select(module->addWire(cell->name.str() + "_sel", 2));
//meta_mux_select.as_wire()->set_bool_attribute("\\maximize");
meta_mux_selects.push_back(meta_mux_select);
new_connections.emplace_back(meta_mux_select, module->Anyconst(cell->name.str() + "_hole", 2, cell->get_src_attribute()));
RTLIL::SigSpec meta_mux1(module->Mux(cell->name.str() + "_mux1", precise_y, imprecise_1_y, meta_mux_select[1]));
RTLIL::SigSpec meta_mux2(module->Mux(cell->name.str() + "_mux2", imprecise_2_y, imprecise_3_y, meta_mux_select[1]));
module->addMux(cell->name.str() + "_mux3", meta_mux1, meta_mux2, meta_mux_select[0], port_taints[Y]);
@ -187,6 +209,30 @@ struct GliftPass : public Pass {
new_taint_outputs.push_back(first.as_wire());
} //end foreach conn in connections
//Create a rough model of area by summing the "weight" score of each meta-mux select:
if (!opt_nomodeloptimize) {
std::vector<RTLIL::SigSpec> meta_mux_select_sums;
std::vector<RTLIL::SigSpec> meta_mux_select_sums_buf;
for (auto &wire : meta_mux_selects) {
meta_mux_select_sums.emplace_back(score_metamux_select(wire));
}
for (unsigned int i = 0; meta_mux_select_sums.size() > 1; ) {
meta_mux_select_sums_buf.clear();
for (i = 0; i + 1 < meta_mux_select_sums.size(); i += 2) {
meta_mux_select_sums_buf.push_back(module->Add(meta_mux_select_sums[i].as_wire()->name.str() + "_add", meta_mux_select_sums[i], meta_mux_select_sums[i+1], false));
}
if (meta_mux_select_sums.size() % 2 == 1)
meta_mux_select_sums_buf.push_back(meta_mux_select_sums[meta_mux_select_sums.size()-1]);
meta_mux_select_sums.swap(meta_mux_select_sums_buf);
}
if (meta_mux_select_sums.size() > 0) {
meta_mux_select_sums[0].as_wire()->set_bool_attribute("\\minimize");
meta_mux_select_sums[0].as_wire()->set_bool_attribute("\\keep");
module->rename(meta_mux_select_sums[0].as_wire(), ID(__glift_weight));
}
}
//Add new connections and mark new module outputs:
for (auto &conn : new_connections)
module->connect(conn);
@ -206,15 +252,17 @@ struct GliftPass : public Pass {
opt_sketchify = false;
opt_taintconstants = false;
opt_keepoutputs = false;
opt_nomodeloptimize = false;
module = nullptr;
args.clear();
argidx = 0;
new_taint_outputs.clear();
meta_mux_selects.clear();
}
public:
GliftPass() : Pass("glift", "create and transform GLIFT models"), opt_create(false), opt_sketchify(false), opt_taintconstants(false), opt_keepoutputs(false), module(nullptr) { }
GliftPass() : Pass("glift", "create and transform GLIFT models"), opt_create(false), opt_sketchify(false), opt_taintconstants(false), opt_keepoutputs(false), opt_nomodeloptimize(false), module(nullptr) { }
void help() YS_OVERRIDE
{
@ -248,7 +296,12 @@ struct GliftPass : public Pass {
log(" alongside the orignal outputs.\n");
log(" (default: original module outputs are removed)\n");
log("\n");
log(" -no-model-optimize\n");
log(" Do not model imprecise taint tracking logic area and attempt to minimize it.\n");
log(" (default: model area and give that signal the \"minimize\" attribute)\n");
log("\n");
}
void execute(std::vector<std::string> _args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing GLIFT pass (creating and manipulating GLIFT models).\n");