From 5f45fe51ea884e58f689bb876f7e6bafa0b86520 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Mon, 20 Apr 2020 21:13:59 +0000 Subject: glift: Add skeleton for `glift` command. --- passes/cmds/Makefile.inc | 1 + passes/cmds/glift.cc | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 passes/cmds/glift.cc (limited to 'passes/cmds') diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 53bfd40c6..5ec2fb6ad 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -18,6 +18,7 @@ OBJS += passes/cmds/setattr.o OBJS += passes/cmds/copy.o OBJS += passes/cmds/splice.o OBJS += passes/cmds/scc.o +OBJS += passes/cmds/glift.o OBJS += passes/cmds/torder.o OBJS += passes/cmds/logcmd.o OBJS += passes/cmds/tee.o diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc new file mode 100644 index 000000000..8ef92ddf7 --- /dev/null +++ b/passes/cmds/glift.cc @@ -0,0 +1,50 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 Alberto Gonzalez + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct GliftPass : public Pass { + GliftPass() : Pass("glift", "create and transform GLIFT models") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" glift [options] [selection]\n"); + log("\n"); + log("Adds, removes, or manipulates gate-level information flow tracking (GLIFT) logic\n"); + log("to the current or specified module.\n"); + log("\n"); + log("Options:"); + log("\n"); + log(" -create"); + log(" Replaces the current or specified module with one that has additional \"taint\"\n"); + log(" inputs, outputs, and internal nets along with precise taint-tracking logic.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + } +} GliftPass; + +PRIVATE_NAMESPACE_END -- cgit v1.2.3 From 09848b3b9f6de98a8663c48cb19d97b46bb0d620 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Tue, 21 Apr 2020 03:21:28 +0000 Subject: glift: Initial implementation of GLIFT model construction. --- passes/cmds/glift.cc | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 173 insertions(+), 2 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 8ef92ddf7..58a5ec1c3 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -25,7 +25,158 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct GliftPass : public Pass { - GliftPass() : Pass("glift", "create and transform GLIFT models") { } + private: + + bool opt_create, opt_taintconstants; + std::vector args; + std::vector::size_type argidx; + RTLIL::Module *module; + + void parse_args() { + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-create") { + opt_create = true; + continue; + } + if (args[argidx] == "-taint-constants") { + opt_taintconstants = true; + continue; + } + break; + } + } + + RTLIL::SigSpec get_corresponding_taint_signal(RTLIL::SigSpec sig) { + RTLIL::SigSpec ret; + + //Get the connected wire for the cell port: + log_assert(sig.is_wire() || sig.is_fully_const()); + log_assert(sig.is_wire() || sig.is_fully_const()); + + //Get a SigSpec for the corresponding taint signal for the cell port, creating one if necessary: + if (sig.is_wire()) { + RTLIL::Wire *w = module->wire(sig.as_wire()->name.str() + "_t"); + if (w == nullptr) w = module->addWire(sig.as_wire()->name.str() + "_t", 1); + ret = w; + } + else if (sig.is_fully_const() && opt_taintconstants) + ret = RTLIL::State::S1; + else if (sig.is_fully_const()) + ret = RTLIL::State::S0; + else + log_cmd_error("Cell port SigSpec has unexpected type.\n"); + + //Finally, if the cell port was a module input or output, make sure the corresponding taint signal is marked, too: + if(sig.is_wire() && sig.as_wire()->port_input) + ret.as_wire()->port_input = true; + if(sig.is_wire() && sig.as_wire()->port_output) + ret.as_wire()->port_output = true; + + return ret; + } + + void create_precise_glift_logic() { + std::vector connections(module->connections()); + std::vector new_connections; + + for(auto &cell : module->cells().to_vector()) { + if (!cell->type.in("$_AND_", "$_OR_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert")) { + log_cmd_error("Invalid cell type \"%s\" found. Module must be techmapped.\n", cell->type.c_str()); + } + if (cell->type.in("$_AND_", "$_OR_")) { + const unsigned int A = 0, B = 1, Y = 2; + const unsigned int NUM_PORTS = 3; + RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::B), cell->getPort(ID::Y)}; + RTLIL::SigSpec port_taints[NUM_PORTS]; + + if (ports[A].size() != 1 || ports[B].size() != 1 || ports[Y].size() != 1) + log_cmd_error("Multi-bit signal found. Run `splitnets` first.\n"); + for (unsigned int i = 0; i < NUM_PORTS; ++i) + port_taints[i] = get_corresponding_taint_signal(ports[i]); + + if (cell->type == "$_AND_") { + //We are basically trying to replace each AND cell with an AN2_SH2 cell: + //module AN2_SH2(A, A_t, B, B_t, Y, Y_t); + // input A, A_t, B, B_t; + // output Y, Y_t; + // + // assign Y = A & B; + // assign Y_t = A & B_t | B & A_t | A_t & B_t; + //endmodule + auto subexpr1 = module->And(cell->name.str() + "_t_1", ports[A], port_taints[B], false, cell->get_src_attribute()); + auto subexpr2 = module->And(cell->name.str() + "_t_2", ports[B], port_taints[A], false, cell->get_src_attribute()); + auto subexpr3 = module->And(cell->name.str() + "_t_3", port_taints[A], port_taints[B], false, cell->get_src_attribute()); + auto subexpr4 = module->Or(cell->name.str() + "_t_4", subexpr1, subexpr2, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_5", subexpr4, subexpr3, port_taints[Y], false, cell->get_src_attribute()); + } + + else if (cell->type == "$_OR_") { + //We are basically trying to replace each OR cell with an OR2_SH2 cell: + //module OR2_SH2(A, A_t, B, B_t, Y, Y_t); + // input A, A_t, B, B_t; + // output Y, Y_t; + // + // assign Y = A | B; + // assign Y_t = ~A & B_t | ~B & A_t | A_t & B_t; + //endmodule + RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_1", ports[A], false, cell->get_src_attribute()); + RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_2", ports[B], false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_3", n_port_a, port_taints[B], false, cell->get_src_attribute()); + auto subexpr2 = module->And(cell->name.str() + "_t_4", n_port_b, port_taints[A], false, cell->get_src_attribute()); + auto subexpr3 = module->And(cell->name.str() + "_t_5", port_taints[A], port_taints[B], false, cell->get_src_attribute()); + auto subexpr4 = module->Or(cell->name.str() + "_t_6", subexpr1, subexpr2, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_7", subexpr4, subexpr3, port_taints[Y], false, cell->get_src_attribute()); + } + + else log_cmd_error("This is a bug (1).\n"); + } + else if (cell->type.in("$_NOT_")) { + const unsigned int A = 0, Y = 1; + const unsigned int NUM_PORTS = 2; + RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::Y)}; + RTLIL::SigSpec port_taints[NUM_PORTS]; + + if (ports[A].size() != 1 || ports[Y].size() != 1) + log_cmd_error("Multi-bit signal found. Run `splitnets` first.\n"); + for (unsigned int i = 0; i < NUM_PORTS; ++i) + port_taints[i] = get_corresponding_taint_signal(ports[i]); + + if (cell->type == "$_NOT_") { + //We are basically trying to replace each NOT cell with an IV_SH2 cell: + //module IV_SH2(A, A_t, Y, Y_t); + // input A, A_t; + // output Y, Y_t; + // + // assign Y = ~A; + // assign Y_t = A_t; + //endmodule + new_connections.emplace_back(port_taints[Y], port_taints[A]); + } + else log_cmd_error("This is a bug (1).\n"); + } + } //end foreach cell in cells + + for (auto &conn : connections) { + RTLIL::SigSpec first = get_corresponding_taint_signal(conn.first); + RTLIL::SigSpec second = get_corresponding_taint_signal(conn.second); + + module->connect(get_corresponding_taint_signal(conn.first), get_corresponding_taint_signal(conn.second)); + + if(conn.second.is_wire() && conn.second.as_wire()->port_input) + second.as_wire()->port_input = true; + if(conn.first.is_wire() && conn.first.as_wire()->port_output) + first.as_wire()->port_output = true; + } //end foreach conn in connections + + for (auto &conn : new_connections) + module->connect(conn); + + module->fixup_ports(); //we have some new taint signals in the module interface + } + + public: + + GliftPass() : Pass("glift", "create and transform GLIFT models"), opt_create(false), opt_taintconstants(false), module(nullptr) { } void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| @@ -41,9 +192,29 @@ struct GliftPass : public Pass { log(" Replaces the current or specified module with one that has additional \"taint\"\n"); log(" inputs, outputs, and internal nets along with precise taint-tracking logic.\n"); log("\n"); + log(" -taint-constants"); + log(" Constant values in the design are labeled as tainted.\n"); + log(" (default: label constants as un-tainted)\n"); + log("\n"); } - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector _args, RTLIL::Design *design) YS_OVERRIDE { + log_header(design, "Executing GLIFT pass (creating and manipulating GLIFT models).\n"); + + args = _args; + parse_args(); + extra_args(args, argidx, design); + + for (auto mod : design->selected_modules()) { + if (module) + log_cmd_error("Only one module may be selected for the glift pass! Flatten the design if necessary. (selected: %s and %s)\n", log_id(module), log_id(mod)); + module = mod; + } + if (module == nullptr) + log_cmd_error("Can't operate on an empty selection!\n"); + + if (opt_create) + create_precise_glift_logic(); } } GliftPass; -- cgit v1.2.3 From 19dafcd4f10f944d6d28acc0b02d0f7e2bd69a03 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Wed, 22 Apr 2020 06:16:12 +0000 Subject: glift: Initial implementation of the `-sketchify` option. --- passes/cmds/glift.cc | 121 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 50 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 58a5ec1c3..bf3f6a73e 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct GliftPass : public Pass { private: - bool opt_create, opt_taintconstants; + bool opt_create, opt_sketchify, opt_taintconstants; std::vector args; std::vector::size_type argidx; RTLIL::Module *module; @@ -38,12 +38,18 @@ struct GliftPass : public Pass { opt_create = true; continue; } + if (args[argidx] == "-sketchify") { + opt_sketchify = true; + continue; + } if (args[argidx] == "-taint-constants") { opt_taintconstants = true; continue; } break; } + if(!opt_create && !opt_sketchify) log_cmd_error("One of `-create` or `-sketchify` must be specified.\n"); + if(opt_create && opt_sketchify) log_cmd_error("Only one of `-create` or `-sketchify` may be specified.\n"); } RTLIL::SigSpec get_corresponding_taint_signal(RTLIL::SigSpec sig) { @@ -75,7 +81,37 @@ struct GliftPass : public Pass { return ret; } - void create_precise_glift_logic() { + void add_precise_GLIFT_logic(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { + //AKA AN2_SH2 or OR2_SH2 + RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_1_1", port_a, false, cell->get_src_attribute()); + RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_1_2", port_b, false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_1_3", (cell->type == "$_AND_")? port_a : n_port_a, port_b_taint, false, cell->get_src_attribute()); + auto subexpr2 = module->And(cell->name.str() + "_t_1_4", (cell->type == "$_AND_")? port_b : n_port_b, port_a_taint, false, cell->get_src_attribute()); + auto subexpr3 = module->And(cell->name.str() + "_t_1_5", port_a_taint, port_b_taint, false, cell->get_src_attribute()); + auto subexpr4 = module->Or(cell->name.str() + "_t_1_6", subexpr1, subexpr2, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_1_7", subexpr4, subexpr3, port_y_taint, false, cell->get_src_attribute()); + } + + void add_imprecise_GLIFT_logic_1(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { + //AKA AN2_SH3 or OR2_SH3 + RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_2_1", port_a, false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_2_2", (cell->type == "$_AND_")? port_b : n_port_a, (cell->type == "$_AND_")? port_a_taint : port_b_taint, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_2_3", (cell->type == "$_AND_")? port_b_taint : port_a_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); + } + + void add_imprecise_GLIFT_logic_2(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { + //AKA AN2_SH4 or OR2_SH4 + RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_3_1", port_b, false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_3_2", (cell->type == "$_AND_")? port_a : n_port_b, (cell->type == "$_AND_")? port_b_taint : port_a_taint, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_3_3", (cell->type == "$_AND_")? port_a_taint : port_b_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); + } + + void add_imprecise_GLIFT_logic_3(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { + //AKA AN2_SH5 or OR2_SH5 + module->addOr(cell->name.str() + "_t_4_1", port_a_taint, port_b_taint, port_y_taint, false, cell->get_src_attribute()); + } + + void create_glift_logic() { std::vector connections(module->connections()); std::vector new_connections; @@ -94,41 +130,27 @@ struct GliftPass : public Pass { for (unsigned int i = 0; i < NUM_PORTS; ++i) port_taints[i] = get_corresponding_taint_signal(ports[i]); - if (cell->type == "$_AND_") { - //We are basically trying to replace each AND cell with an AN2_SH2 cell: - //module AN2_SH2(A, A_t, B, B_t, Y, Y_t); - // input A, A_t, B, B_t; - // output Y, Y_t; - // - // assign Y = A & B; - // assign Y_t = A & B_t | B & A_t | A_t & B_t; - //endmodule - auto subexpr1 = module->And(cell->name.str() + "_t_1", ports[A], port_taints[B], false, cell->get_src_attribute()); - auto subexpr2 = module->And(cell->name.str() + "_t_2", ports[B], port_taints[A], false, cell->get_src_attribute()); - auto subexpr3 = module->And(cell->name.str() + "_t_3", port_taints[A], port_taints[B], false, cell->get_src_attribute()); - auto subexpr4 = module->Or(cell->name.str() + "_t_4", subexpr1, subexpr2, false, cell->get_src_attribute()); - module->addOr(cell->name.str() + "_t_5", subexpr4, subexpr3, port_taints[Y], false, cell->get_src_attribute()); - } - - else if (cell->type == "$_OR_") { - //We are basically trying to replace each OR cell with an OR2_SH2 cell: - //module OR2_SH2(A, A_t, B, B_t, Y, Y_t); - // input A, A_t, B, B_t; - // output Y, Y_t; - // - // assign Y = A | B; - // assign Y_t = ~A & B_t | ~B & A_t | A_t & B_t; - //endmodule - RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_1", ports[A], false, cell->get_src_attribute()); - RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_2", ports[B], false, cell->get_src_attribute()); - auto subexpr1 = module->And(cell->name.str() + "_t_3", n_port_a, port_taints[B], false, cell->get_src_attribute()); - auto subexpr2 = module->And(cell->name.str() + "_t_4", n_port_b, port_taints[A], false, cell->get_src_attribute()); - auto subexpr3 = module->And(cell->name.str() + "_t_5", port_taints[A], port_taints[B], false, cell->get_src_attribute()); - auto subexpr4 = module->Or(cell->name.str() + "_t_6", subexpr1, subexpr2, false, cell->get_src_attribute()); - module->addOr(cell->name.str() + "_t_7", subexpr4, subexpr3, port_taints[Y], false, cell->get_src_attribute()); + if (opt_create) + add_precise_GLIFT_logic(cell, ports[A], port_taints[A], ports[B], port_taints[B], port_taints[Y]); + else if (opt_sketchify) { + RTLIL::SigSpec precise_y(module->addWire(cell->name.str() + "_y1", 1)), + imprecise_1_y(module->addWire(cell->name.str() + "_y2", 1)), + imprecise_2_y(module->addWire(cell->name.str() + "_y3", 1)), + imprecise_3_y(module->addWire(cell->name.str() + "_y4", 1)); + + add_precise_GLIFT_logic(cell, ports[A], port_taints[A], ports[B], port_taints[B], precise_y); + add_imprecise_GLIFT_logic_1(cell, ports[A], port_taints[A], ports[B], port_taints[B], imprecise_1_y); + add_imprecise_GLIFT_logic_2(cell, ports[A], port_taints[A], ports[B], port_taints[B], imprecise_2_y); + 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"); + 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]); } - - else log_cmd_error("This is a bug (1).\n"); + else log_cmd_error("This is a bug (2).\n"); } else if (cell->type.in("$_NOT_")) { const unsigned int A = 0, Y = 1; @@ -142,17 +164,9 @@ struct GliftPass : public Pass { port_taints[i] = get_corresponding_taint_signal(ports[i]); if (cell->type == "$_NOT_") { - //We are basically trying to replace each NOT cell with an IV_SH2 cell: - //module IV_SH2(A, A_t, Y, Y_t); - // input A, A_t; - // output Y, Y_t; - // - // assign Y = ~A; - // assign Y_t = A_t; - //endmodule new_connections.emplace_back(port_taints[Y], port_taints[A]); } - else log_cmd_error("This is a bug (1).\n"); + else log_cmd_error("This is a bug (3).\n"); } } //end foreach cell in cells @@ -176,22 +190,30 @@ struct GliftPass : public Pass { public: - GliftPass() : Pass("glift", "create and transform GLIFT models"), opt_create(false), opt_taintconstants(false), module(nullptr) { } + GliftPass() : Pass("glift", "create and transform GLIFT models"), opt_create(false), opt_sketchify(false), opt_taintconstants(false), module(nullptr) { } void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" glift [options] [selection]\n"); + log(" glift -create|-sketchify [options] [selection]\n"); log("\n"); log("Adds, removes, or manipulates gate-level information flow tracking (GLIFT) logic\n"); log("to the current or specified module.\n"); log("\n"); - log("Options:"); + log("Commands:"); log("\n"); log(" -create"); log(" Replaces the current or specified module with one that has additional \"taint\"\n"); log(" inputs, outputs, and internal nets along with precise taint-tracking logic.\n"); log("\n"); + log(" -sketchify"); + log(" Replaces the current or specified module with one that has additional \"taint\"\n"); + log(" inputs, outputs, and internal nets along with varying-precision taint-tracking logic.\n"); + log(" Which version of taint tracking logic is used at a given cell is determined by a MUX\n"); + log(" selected by an $anyconst cell.\n"); + log("\n"); + log("Options:"); + log("\n"); log(" -taint-constants"); log(" Constant values in the design are labeled as tainted.\n"); log(" (default: label constants as un-tainted)\n"); @@ -213,8 +235,7 @@ struct GliftPass : public Pass { if (module == nullptr) log_cmd_error("Can't operate on an empty selection!\n"); - if (opt_create) - create_precise_glift_logic(); + create_glift_logic(); } } GliftPass; -- cgit v1.2.3 From c36440a7ee158f6d9072913358d2cb15badc4a75 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Wed, 22 Apr 2020 21:33:22 +0000 Subject: glift: Remove outputs by default; add `-keep-outputs` option; properly reset internal state between calls. --- passes/cmds/glift.cc | 55 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 12 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index bf3f6a73e..b8c33a3f1 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -27,9 +27,10 @@ PRIVATE_NAMESPACE_BEGIN struct GliftPass : public Pass { private: - bool opt_create, opt_sketchify, opt_taintconstants; + bool opt_create, opt_sketchify, opt_taintconstants, opt_keepoutputs; std::vector args; std::vector::size_type argidx; + std::vector new_taint_outputs; RTLIL::Module *module; void parse_args() { @@ -46,6 +47,10 @@ struct GliftPass : public Pass { opt_taintconstants = true; continue; } + if (args[argidx] == "-keep-outputs") { + opt_keepoutputs = true; + continue; + } break; } if(!opt_create && !opt_sketchify) log_cmd_error("One of `-create` or `-sketchify` must be specified.\n"); @@ -76,7 +81,7 @@ struct GliftPass : public Pass { if(sig.is_wire() && sig.as_wire()->port_input) ret.as_wire()->port_input = true; if(sig.is_wire() && sig.as_wire()->port_output) - ret.as_wire()->port_output = true; + new_taint_outputs.push_back(ret.as_wire()); return ret; } @@ -144,13 +149,13 @@ 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_select.as_wire()->set_bool_attribute("\\maximize"); 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]); } - else log_cmd_error("This is a bug (2).\n"); + else log_cmd_error("This is a bug (1).\n"); } else if (cell->type.in("$_NOT_")) { const unsigned int A = 0, Y = 1; @@ -166,7 +171,7 @@ struct GliftPass : public Pass { if (cell->type == "$_NOT_") { new_connections.emplace_back(port_taints[Y], port_taints[A]); } - else log_cmd_error("This is a bug (3).\n"); + else log_cmd_error("This is a bug (2).\n"); } } //end foreach cell in cells @@ -179,18 +184,38 @@ struct GliftPass : public Pass { if(conn.second.is_wire() && conn.second.as_wire()->port_input) second.as_wire()->port_input = true; if(conn.first.is_wire() && conn.first.as_wire()->port_output) - first.as_wire()->port_output = true; + new_taint_outputs.push_back(first.as_wire()); } //end foreach conn in connections for (auto &conn : new_connections) module->connect(conn); + for (auto &port_name : module->ports) { + RTLIL::Wire *port = module->wire(port_name); + log_assert(port != nullptr); + if (port->port_output && !opt_keepoutputs) + port->port_output = false; + } + for (auto &output : new_taint_outputs) + output->port_output = true; module->fixup_ports(); //we have some new taint signals in the module interface } + void reset() { + opt_create = false; + opt_sketchify = false; + opt_taintconstants = false; + opt_keepoutputs = false; + module = nullptr; + args.clear(); + argidx = 0; + new_taint_outputs.clear(); + } + public: - GliftPass() : Pass("glift", "create and transform GLIFT models"), opt_create(false), opt_sketchify(false), opt_taintconstants(false), module(nullptr) { } + GliftPass() : Pass("glift", "create and transform GLIFT models"), opt_create(false), opt_sketchify(false), opt_taintconstants(false), opt_keepoutputs(false), module(nullptr) { } + void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| @@ -200,29 +225,35 @@ struct GliftPass : public Pass { log("Adds, removes, or manipulates gate-level information flow tracking (GLIFT) logic\n"); log("to the current or specified module.\n"); log("\n"); - log("Commands:"); + log("Commands:\n"); log("\n"); - log(" -create"); + log(" -create\n"); log(" Replaces the current or specified module with one that has additional \"taint\"\n"); log(" inputs, outputs, and internal nets along with precise taint-tracking logic.\n"); log("\n"); - log(" -sketchify"); + log(" -sketchify\n"); log(" Replaces the current or specified module with one that has additional \"taint\"\n"); log(" inputs, outputs, and internal nets along with varying-precision taint-tracking logic.\n"); log(" Which version of taint tracking logic is used at a given cell is determined by a MUX\n"); log(" selected by an $anyconst cell.\n"); log("\n"); - log("Options:"); + log("Options:\n"); log("\n"); - log(" -taint-constants"); + log(" -taint-constants\n"); log(" Constant values in the design are labeled as tainted.\n"); log(" (default: label constants as un-tainted)\n"); log("\n"); + log(" -keep-outputs\n"); + log(" Do not remove module outputs. Taint tracking outputs will appear in the module ports\n"); + log(" alongside the orignal outputs.\n"); + log(" (default: original module outputs are removed)\n"); + log("\n"); } void execute(std::vector _args, RTLIL::Design *design) YS_OVERRIDE { log_header(design, "Executing GLIFT pass (creating and manipulating GLIFT models).\n"); + reset(); args = _args; parse_args(); extra_args(args, argidx, design); -- cgit v1.2.3 From 72cebef279357435cde115851bc095375763108c Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Thu, 23 Apr 2020 06:41:58 +0000 Subject: glift: Add replacement scoring and area minimization option. --- passes/cmds/glift.cc | 59 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index b8c33a3f1..b35179fd1 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -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 args; std::vector::size_type argidx; std::vector new_taint_outputs; + std::vector 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 connections(module->connections()); std::vector 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 meta_mux_select_sums; + std::vector 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 _args, RTLIL::Design *design) YS_OVERRIDE { log_header(design, "Executing GLIFT pass (creating and manipulating GLIFT models).\n"); -- cgit v1.2.3 From ddfb9f08e20557ab434017a053f14067992b0ea9 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Tue, 28 Apr 2020 06:13:12 +0000 Subject: glift: Add `-create-imprecise` command, rename other commands, and re-work the help text. --- passes/cmds/glift.cc | 82 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 28 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index b35179fd1..8296e7194 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -27,21 +27,28 @@ PRIVATE_NAMESPACE_BEGIN struct GliftPass : public Pass { private: - bool opt_create, opt_sketchify, opt_taintconstants, opt_keepoutputs, opt_nomodeloptimize; + bool opt_create_precise, opt_create_imprecise, opt_create_sketch; + bool opt_taintconstants, opt_keepoutputs, opt_nocostmodel; std::vector args; std::vector::size_type argidx; std::vector new_taint_outputs; std::vector meta_mux_selects; RTLIL::Module *module; + const RTLIL::IdString cost_model_wire_name = ID(__glift_weight); + void parse_args() { for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-create") { - opt_create = true; + if (args[argidx] == "-create-precise") { + opt_create_precise = true; + continue; + } + if (args[argidx] == "-create-imprecise") { + opt_create_imprecise = true; continue; } - if (args[argidx] == "-sketchify") { - opt_sketchify = true; + if (args[argidx] == "-create-sketch") { + opt_create_sketch = true; continue; } if (args[argidx] == "-taint-constants") { @@ -52,14 +59,16 @@ struct GliftPass : public Pass { opt_keepoutputs = true; continue; } - if (args[argidx] == "-no-model-optimize") { - opt_nomodeloptimize = true; + if (args[argidx] == "-no-cost-model") { + opt_nocostmodel = true; continue; } break; } - if(!opt_create && !opt_sketchify) log_cmd_error("One of `-create` or `-sketchify` must be specified.\n"); - if(opt_create && opt_sketchify) log_cmd_error("Only one of `-create` or `-sketchify` may be specified.\n"); + if(!opt_create_precise && !opt_create_imprecise && !opt_create_sketch) + log_cmd_error("No command provided. See help for usage.\n"); + if(static_cast(opt_create_precise) + static_cast(opt_create_imprecise) + static_cast(opt_create_sketch) != 1) + log_cmd_error("Only one command may be specified. See help for usage.\n"); } RTLIL::SigSpec get_corresponding_taint_signal(RTLIL::SigSpec sig) { @@ -156,9 +165,11 @@ struct GliftPass : public Pass { for (unsigned int i = 0; i < NUM_PORTS; ++i) port_taints[i] = get_corresponding_taint_signal(ports[i]); - if (opt_create) + if (opt_create_precise) add_precise_GLIFT_logic(cell, ports[A], port_taints[A], ports[B], port_taints[B], port_taints[Y]); - else if (opt_sketchify) { + else if (opt_create_imprecise) + add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], port_taints[Y]); + else if (opt_create_sketch) { RTLIL::SigSpec precise_y(module->addWire(cell->name.str() + "_y1", 1)), imprecise_1_y(module->addWire(cell->name.str() + "_y2", 1)), imprecise_2_y(module->addWire(cell->name.str() + "_y3", 1)), @@ -210,7 +221,7 @@ struct GliftPass : public Pass { } //end foreach conn in connections //Create a rough model of area by summing the "weight" score of each meta-mux select: - if (!opt_nomodeloptimize) { + if (!opt_nocostmodel) { std::vector meta_mux_select_sums; std::vector meta_mux_select_sums_buf; for (auto &wire : meta_mux_selects) { @@ -228,7 +239,7 @@ struct GliftPass : public Pass { 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)); + module->rename(meta_mux_select_sums[0].as_wire(), cost_model_wire_name); } } @@ -248,11 +259,12 @@ struct GliftPass : public Pass { } void reset() { - opt_create = false; - opt_sketchify = false; + opt_create_precise = false; + opt_create_imprecise = false; + opt_create_sketch = false; opt_taintconstants = false; opt_keepoutputs = false; - opt_nomodeloptimize = false; + opt_nocostmodel = false; module = nullptr; args.clear(); argidx = 0; @@ -262,28 +274,41 @@ struct GliftPass : public Pass { public: - 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) { } + GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise(false), opt_create_imprecise(false), opt_create_sketch(false), opt_taintconstants(false), opt_keepoutputs(false), opt_nocostmodel(false), module(nullptr) { } void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" glift -create|-sketchify [options] [selection]\n"); + log(" glift [options] [selection]\n"); + log("\n"); + log("Augments the current or specified module with gate-level information flow tracking\n"); + log("(GLIFT) logic using the \"constructive mapping\" approach. Also can set up QBF-SAT\n"); + log("optimization problems in order to optimize GLIFT models or trade off precision and\n"); + log("complexity.\n"); log("\n"); - log("Adds, removes, or manipulates gate-level information flow tracking (GLIFT) logic\n"); - log("to the current or specified module.\n"); log("\n"); log("Commands:\n"); log("\n"); - log(" -create\n"); + log(" -create-precise\n"); log(" Replaces the current or specified module with one that has additional \"taint\"\n"); log(" inputs, outputs, and internal nets along with precise taint-tracking logic.\n"); log("\n"); - log(" -sketchify\n"); + log(" -create-imprecise\n"); log(" Replaces the current or specified module with one that has additional \"taint\"\n"); - log(" inputs, outputs, and internal nets along with varying-precision taint-tracking logic.\n"); - log(" Which version of taint tracking logic is used at a given cell is determined by a MUX\n"); - log(" selected by an $anyconst cell.\n"); + log(" inputs, outputs, and internal nets along with imprecise \"All OR\" taint-tracking\n"); + log(" logic.\n"); + log("\n"); + log(" -create-sketch\n"); + log(" Replaces the current or specified module with one that has additional \"taint\"\n"); + log(" inputs, outputs, and internal nets along with varying-precision taint-tracking\n"); + log(" logic. Which version of taint tracking logic is used at a given cell is determined\n"); + log(" by a MUX selected by an $anyconst cell. By default, unless the `-no-cost-model`\n"); + log(" option is provided, an additional wire named `__glift_weight` with the `keep` and\n"); + log(" `minimize` attributes is added to the module along with pmuxes and adders to\n"); + log(" calculate a rough estimate of the number of logic gates in the GLIFT model given\n"); + log(" an assignment for the $anyconst cells.\n"); + log("\n"); log("\n"); log("Options:\n"); log("\n"); @@ -296,9 +321,10 @@ 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(" -no-cost-model\n"); + log(" Do not model taint tracking logic area and do not create a `__glift_weight` wire.\n"); + log(" Only applicable in combination with `-create-sketch`.\n"); + log(" (default: model area and give that wire the \"keep\" and \"minimize\" attributes)\n"); log("\n"); } -- cgit v1.2.3 From bc207d5426c5c41e103ca54dbb31cab573d66df2 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Tue, 9 Jun 2020 22:56:57 +0000 Subject: glift: Change command names to better represent their functions. --- passes/cmds/glift.cc | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 8296e7194..1ed5de76a 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct GliftPass : public Pass { private: - bool opt_create_precise, opt_create_imprecise, opt_create_sketch; + bool opt_create_precise_model, opt_create_imprecise_model, opt_create_instrumented_model; bool opt_taintconstants, opt_keepoutputs, opt_nocostmodel; std::vector args; std::vector::size_type argidx; @@ -39,16 +39,16 @@ struct GliftPass : public Pass { void parse_args() { for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-create-precise") { - opt_create_precise = true; + if (args[argidx] == "-create-precise-model") { + opt_create_precise_model = true; continue; } - if (args[argidx] == "-create-imprecise") { - opt_create_imprecise = true; + if (args[argidx] == "-create-imprecise-model") { + opt_create_imprecise_model = true; continue; } - if (args[argidx] == "-create-sketch") { - opt_create_sketch = true; + if (args[argidx] == "-create-instrumented-model") { + opt_create_instrumented_model = true; continue; } if (args[argidx] == "-taint-constants") { @@ -65,9 +65,9 @@ struct GliftPass : public Pass { } break; } - if(!opt_create_precise && !opt_create_imprecise && !opt_create_sketch) + if(!opt_create_precise_model && !opt_create_imprecise_model && !opt_create_instrumented_model) log_cmd_error("No command provided. See help for usage.\n"); - if(static_cast(opt_create_precise) + static_cast(opt_create_imprecise) + static_cast(opt_create_sketch) != 1) + if(static_cast(opt_create_precise_model) + static_cast(opt_create_imprecise_model) + static_cast(opt_create_instrumented_model) != 1) log_cmd_error("Only one command may be specified. See help for usage.\n"); } @@ -165,11 +165,11 @@ struct GliftPass : public Pass { for (unsigned int i = 0; i < NUM_PORTS; ++i) port_taints[i] = get_corresponding_taint_signal(ports[i]); - if (opt_create_precise) + if (opt_create_precise_model) add_precise_GLIFT_logic(cell, ports[A], port_taints[A], ports[B], port_taints[B], port_taints[Y]); - else if (opt_create_imprecise) + else if (opt_create_imprecise_model) add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], port_taints[Y]); - else if (opt_create_sketch) { + else if (opt_create_instrumented_model) { RTLIL::SigSpec precise_y(module->addWire(cell->name.str() + "_y1", 1)), imprecise_1_y(module->addWire(cell->name.str() + "_y2", 1)), imprecise_2_y(module->addWire(cell->name.str() + "_y3", 1)), @@ -259,9 +259,9 @@ struct GliftPass : public Pass { } void reset() { - opt_create_precise = false; - opt_create_imprecise = false; - opt_create_sketch = false; + opt_create_precise_model = false; + opt_create_imprecise_model = false; + opt_create_instrumented_model = false; opt_taintconstants = false; opt_keepoutputs = false; opt_nocostmodel = false; @@ -274,7 +274,7 @@ struct GliftPass : public Pass { public: - GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise(false), opt_create_imprecise(false), opt_create_sketch(false), opt_taintconstants(false), opt_keepoutputs(false), opt_nocostmodel(false), module(nullptr) { } + GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise_model(false), opt_create_imprecise_model(false), opt_create_instrumented_model(false), opt_taintconstants(false), opt_keepoutputs(false), opt_nocostmodel(false), module(nullptr) { } void help() YS_OVERRIDE { @@ -290,17 +290,17 @@ struct GliftPass : public Pass { log("\n"); log("Commands:\n"); log("\n"); - log(" -create-precise\n"); - log(" Replaces the current or specified module with one that has additional \"taint\"\n"); + log(" -create-precise-model\n"); + log(" Replaces the current or specified module with one that has corresponding \"taint\"\n"); log(" inputs, outputs, and internal nets along with precise taint-tracking logic.\n"); log("\n"); - log(" -create-imprecise\n"); - log(" Replaces the current or specified module with one that has additional \"taint\"\n"); + log(" -create-imprecise-model\n"); + log(" Replaces the current or specified module with one that has corresponding \"taint\"\n"); log(" inputs, outputs, and internal nets along with imprecise \"All OR\" taint-tracking\n"); log(" logic.\n"); log("\n"); - log(" -create-sketch\n"); - log(" Replaces the current or specified module with one that has additional \"taint\"\n"); + log(" -create-instrumented-model\n"); + log(" Replaces the current or specified module with one that has corresponding \"taint\"\n"); log(" inputs, outputs, and internal nets along with varying-precision taint-tracking\n"); log(" logic. Which version of taint tracking logic is used at a given cell is determined\n"); log(" by a MUX selected by an $anyconst cell. By default, unless the `-no-cost-model`\n"); -- cgit v1.2.3 From 26bd68625946aaac70cfe927755785b7f1a79efd Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Wed, 10 Jun 2020 00:31:46 +0000 Subject: glift: Add `-instrument-more` option to add 4 more versions of taint tracking logic. Also refactor a bit and update help text. --- passes/cmds/glift.cc | 168 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 124 insertions(+), 44 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 1ed5de76a..42175859f 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -28,7 +28,7 @@ struct GliftPass : public Pass { private: bool opt_create_precise_model, opt_create_imprecise_model, opt_create_instrumented_model; - bool opt_taintconstants, opt_keepoutputs, opt_nocostmodel; + bool opt_taintconstants, opt_keepoutputs, opt_nocostmodel, opt_instrumentmore; std::vector args; std::vector::size_type argidx; std::vector new_taint_outputs; @@ -63,6 +63,10 @@ struct GliftPass : public Pass { opt_nocostmodel = true; continue; } + if (args[argidx] == "-instrument-more") { + opt_instrumentmore = true; + continue; + } break; } if(!opt_create_precise_model && !opt_create_imprecise_model && !opt_create_instrumented_model) @@ -130,25 +134,48 @@ 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()); } + void add_imprecise_GLIFT_logic_4(RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_y_taint) { + module->connect(port_y_taint, port_a_taint); + } + + void add_imprecise_GLIFT_logic_5(RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { + module->connect(port_y_taint, port_b_taint); + } + + void add_imprecise_GLIFT_logic_6(RTLIL::SigSpec &port_y_taint) { + module->connect(port_y_taint, RTLIL::Const(1, 1)); + } + + void add_imprecise_GLIFT_logic_7(RTLIL::SigSpec &port_y_taint) { + module->connect(port_y_taint, RTLIL::Const(0, 1)); + } + 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); + auto num_versions = opt_instrumentmore? 8 : 4; + auto select_width = log2(num_versions); + log_assert(metamux_select.as_wire()->width == select_width); - 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()); + std::vector costs = {5, 2, 2, 1, 0, 0, 0, 0}; //in terms of AND/OR gates - return ret; + std::vector next_pmux_y_ports, pmux_y_ports(costs.begin(), costs.begin() + num_versions); + for (auto i = 0; pmux_y_ports.size() > 1; ++i) { + for (auto j = 0; j+1 < GetSize(pmux_y_ports); j += 2) { + next_pmux_y_ports.emplace_back(module->Pmux(stringf("%s_mux_%d_%d", metamux_select.as_wire()->name.c_str(), i, j), pmux_y_ports[j], pmux_y_ports[j+1], metamux_select[GetSize(metamux_select) - 1 - i], metamux_select.as_wire()->get_src_attribute())); + } + if (GetSize(pmux_y_ports) % 2 == 1) + next_pmux_y_ports.push_back(pmux_y_ports[GetSize(pmux_y_ports) - 1]); + pmux_y_ports.swap(next_pmux_y_ports); + next_pmux_y_ports.clear(); + } + + log_assert(pmux_y_ports.size() == 1); + return pmux_y_ports[0]; } void create_glift_logic() { std::vector connections(module->connections()); - std::vector new_connections; for(auto &cell : module->cells().to_vector()) { if (!cell->type.in("$_AND_", "$_OR_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert")) { @@ -170,23 +197,52 @@ struct GliftPass : public Pass { else if (opt_create_imprecise_model) add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], port_taints[Y]); else if (opt_create_instrumented_model) { - RTLIL::SigSpec precise_y(module->addWire(cell->name.str() + "_y1", 1)), - imprecise_1_y(module->addWire(cell->name.str() + "_y2", 1)), - imprecise_2_y(module->addWire(cell->name.str() + "_y3", 1)), - imprecise_3_y(module->addWire(cell->name.str() + "_y4", 1)); - - add_precise_GLIFT_logic(cell, ports[A], port_taints[A], ports[B], port_taints[B], precise_y); - add_imprecise_GLIFT_logic_1(cell, ports[A], port_taints[A], ports[B], port_taints[B], imprecise_1_y); - add_imprecise_GLIFT_logic_2(cell, ports[A], port_taints[A], ports[B], port_taints[B], imprecise_2_y); - 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)); + std::vector taint_version; + int num_versions = opt_instrumentmore? 8 : 4; + + for (auto i = 1; i <= num_versions; ++i) + taint_version.emplace_back(RTLIL::SigSpec(module->addWire(stringf("%s_y%d", cell->name.c_str(), i), 1))); + + for (auto i = 0; i < num_versions; ++i) { + switch(i) { + case 0: add_precise_GLIFT_logic(cell, ports[A], port_taints[A], ports[B], port_taints[B], taint_version[i]); + break; + case 1: add_imprecise_GLIFT_logic_1(cell, ports[A], port_taints[A], ports[B], port_taints[B], taint_version[i]); + break; + case 2: add_imprecise_GLIFT_logic_2(cell, ports[A], port_taints[A], ports[B], port_taints[B], taint_version[i]); + break; + case 3: add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], taint_version[i]); + break; + case 4: add_imprecise_GLIFT_logic_4(port_taints[A], taint_version[i]); + break; + case 5: add_imprecise_GLIFT_logic_5(port_taints[B], taint_version[i]); + break; + case 6: add_imprecise_GLIFT_logic_6(taint_version[i]); + break; + case 7: add_imprecise_GLIFT_logic_7(taint_version[i]); + break; + default: log_assert(false); + } + } + + auto select_width = log2(num_versions); + log_assert(exp2(select_width) == num_versions); + RTLIL::SigSpec meta_mux_select(module->addWire(cell->name.str() + "_sel", select_width)); 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]); + module->connect(meta_mux_select, module->Anyconst(cell->name.str() + "_hole", select_width, cell->get_src_attribute())); + + std::vector next_meta_mux_y_ports, meta_mux_y_ports(taint_version); + for (auto i = 0; meta_mux_y_ports.size() > 1; ++i) { + for (auto j = 0; j+1 < GetSize(meta_mux_y_ports); j += 2) { + next_meta_mux_y_ports.emplace_back(module->Mux(stringf("%s_mux_%d_%d", cell->name.c_str(), i, j), meta_mux_y_ports[j], meta_mux_y_ports[j+1], meta_mux_select[GetSize(meta_mux_select) - 1 - i])); + } + if (GetSize(meta_mux_y_ports) % 2 == 1) + next_meta_mux_y_ports.push_back(meta_mux_y_ports[GetSize(meta_mux_y_ports) - 1]); + meta_mux_y_ports.swap(next_meta_mux_y_ports); + next_meta_mux_y_ports.clear(); + } + log_assert(meta_mux_y_ports.size() == 1); + module->connect(port_taints[Y], meta_mux_y_ports[0]); } else log_cmd_error("This is a bug (1).\n"); } @@ -202,7 +258,7 @@ struct GliftPass : public Pass { port_taints[i] = get_corresponding_taint_signal(ports[i]); if (cell->type == "$_NOT_") { - new_connections.emplace_back(port_taints[Y], port_taints[A]); + module->connect(port_taints[Y], port_taints[A]); } else log_cmd_error("This is a bug (2).\n"); } @@ -243,10 +299,7 @@ struct GliftPass : public Pass { } } - //Add new connections and mark new module outputs: - for (auto &conn : new_connections) - module->connect(conn); - + //Mark new module outputs: for (auto &port_name : module->ports) { RTLIL::Wire *port = module->wire(port_name); log_assert(port != nullptr); @@ -265,6 +318,7 @@ struct GliftPass : public Pass { opt_taintconstants = false; opt_keepoutputs = false; opt_nocostmodel = false; + opt_instrumentmore = false; module = nullptr; args.clear(); argidx = 0; @@ -274,7 +328,7 @@ struct GliftPass : public Pass { public: - GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise_model(false), opt_create_imprecise_model(false), opt_create_instrumented_model(false), opt_taintconstants(false), opt_keepoutputs(false), opt_nocostmodel(false), module(nullptr) { } + GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise_model(false), opt_create_imprecise_model(false), opt_create_instrumented_model(false), opt_taintconstants(false), opt_keepoutputs(false), opt_nocostmodel(false), opt_instrumentmore(false), module(nullptr) { } void help() YS_OVERRIDE { @@ -292,22 +346,35 @@ struct GliftPass : public Pass { log("\n"); log(" -create-precise-model\n"); log(" Replaces the current or specified module with one that has corresponding \"taint\"\n"); - log(" inputs, outputs, and internal nets along with precise taint-tracking logic.\n"); + log(" inputs, outputs, and internal nets along with precise taint tracking logic.\n"); + log(" For example, precise taint tracking logic for an AND gate is:\n"); + log("\n"); + log(" y_t = a & b_t | b & a_t | a_t & b_t\n"); + log("\n"); log("\n"); log(" -create-imprecise-model\n"); log(" Replaces the current or specified module with one that has corresponding \"taint\"\n"); - log(" inputs, outputs, and internal nets along with imprecise \"All OR\" taint-tracking\n"); - log(" logic.\n"); + log(" inputs, outputs, and internal nets along with imprecise \"All OR\" taint tracking\n"); + log(" logic:\n"); + log("\n"); + log(" y_t = a_t | b_t\n"); + log("\n"); log("\n"); log(" -create-instrumented-model\n"); log(" Replaces the current or specified module with one that has corresponding \"taint\"\n"); - log(" inputs, outputs, and internal nets along with varying-precision taint-tracking\n"); - log(" logic. Which version of taint tracking logic is used at a given cell is determined\n"); - log(" by a MUX selected by an $anyconst cell. By default, unless the `-no-cost-model`\n"); - log(" option is provided, an additional wire named `__glift_weight` with the `keep` and\n"); - log(" `minimize` attributes is added to the module along with pmuxes and adders to\n"); - log(" calculate a rough estimate of the number of logic gates in the GLIFT model given\n"); - log(" an assignment for the $anyconst cells.\n"); + log(" inputs, outputs, and internal nets along with 4 varying-precision versions of taint\n"); + log(" tracking logic. Which version of taint tracking logic is used for a given gate is\n"); + log(" determined by a MUX selected by an $anyconst cell. By default, unless the\n"); + log(" `-no-cost-model` option is provided, an additional wire named `__glift_weight` with\n"); + log(" the `keep` and `minimize` attributes is added to the module along with pmuxes and\n"); + log(" adders to calculate a rough estimate of the number of logic gates in the GLIFT model\n"); + log(" given an assignment for the $anyconst cells. The four versions of taint tracking logic\n"); + log(" for an AND gate are:"); + log("\n"); + log(" y_t = a & b_t | b & a_t | a_t & b_t (like `-create-precise-model`)\n"); + log(" y_t = a_t | a & b_t\n"); + log(" y_t = b_t | b & a_t\n"); + log(" y_t = a_t | b_t (like `-create-imprecise-model`)\n"); log("\n"); log("\n"); log("Options:\n"); @@ -323,9 +390,22 @@ struct GliftPass : public Pass { log("\n"); log(" -no-cost-model\n"); log(" Do not model taint tracking logic area and do not create a `__glift_weight` wire.\n"); - log(" Only applicable in combination with `-create-sketch`.\n"); + log(" Only applicable in combination with `-create-instrumented-model`.\n"); log(" (default: model area and give that wire the \"keep\" and \"minimize\" attributes)\n"); log("\n"); + log(" -instrument-more\n"); + log(" Allow choice from more versions of (even simpler) taint tracking logic. A total\n"); + log(" of 8 versions of taint tracking logic will be added per gate, including the 4\n"); + log(" versions from `-create-instrumented-model` and these additional versions:\n"); + log("\n"); + log(" y_t = a_t\n"); + log(" y_t = b_t\n"); + log(" y_t = 1\n"); + log(" y_t = 0\n"); + log("\n"); + log(" Only applicable in combination with `-create-instrumented-model`.\n"); + log(" (default: do not add more versions of taint tracking logic.\n"); + log("\n"); } void execute(std::vector _args, RTLIL::Design *design) YS_OVERRIDE -- cgit v1.2.3 From 91c20fca724b1f3ec1d0208a9e135b5abd75c0c1 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Sat, 13 Jun 2020 08:20:01 +0000 Subject: glift: Add `-simple-cost-model` option Rather than assigning specific weights to specific versions of taint tracking logic and summing the weights of all GLIFT cells, sum the following values for each GLIFT cell: - 0 if the associated hole/$anyconst cell value is non-zero, i.e. reduced-precision taint tracking logic is chosen at this cell - 1 if the associated hole/$anyconst cell value is zero, i.e. the full-precision taint tracking logic is chosen at this cell This simplified cost modeling reduces the potential for the QBF-SAT solver to minimize taint tracking logic area but significantly simplifies the QBF-SAT problem. --- passes/cmds/glift.cc | 65 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 20 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 42175859f..eee1b2c79 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -28,7 +28,7 @@ struct GliftPass : public Pass { private: bool opt_create_precise_model, opt_create_imprecise_model, opt_create_instrumented_model; - bool opt_taintconstants, opt_keepoutputs, opt_nocostmodel, opt_instrumentmore; + bool opt_taintconstants, opt_keepoutputs, opt_simplecostmodel, opt_nocostmodel, opt_instrumentmore; std::vector args; std::vector::size_type argidx; std::vector new_taint_outputs; @@ -59,6 +59,10 @@ struct GliftPass : public Pass { opt_keepoutputs = true; continue; } + if (args[argidx] == "-simple-cost-model") { + opt_simplecostmodel = true; + continue; + } if (args[argidx] == "-no-cost-model") { opt_nocostmodel = true; continue; @@ -73,6 +77,10 @@ struct GliftPass : public Pass { log_cmd_error("No command provided. See help for usage.\n"); if(static_cast(opt_create_precise_model) + static_cast(opt_create_imprecise_model) + static_cast(opt_create_instrumented_model) != 1) log_cmd_error("Only one command may be specified. See help for usage.\n"); + if(opt_simplecostmodel && opt_nocostmodel) + log_cmd_error("Only one of `-simple-cost-model` and `-no-cost-model` may be specified. See help for usage.\n"); + if((opt_simplecostmodel || opt_nocostmodel) && !opt_create_instrumented_model) + log_cmd_error("Options `-simple-cost-model` and `-no-cost-model` may only be used with `-create-instrumented-model`. See help for usage.\n"); } RTLIL::SigSpec get_corresponding_taint_signal(RTLIL::SigSpec sig) { @@ -153,25 +161,33 @@ struct GliftPass : public Pass { RTLIL::SigSpec score_metamux_select(const RTLIL::SigSpec &metamux_select) { log_assert(metamux_select.is_wire()); - auto num_versions = opt_instrumentmore? 8 : 4; - auto select_width = log2(num_versions); - log_assert(metamux_select.as_wire()->width == select_width); - - std::vector costs = {5, 2, 2, 1, 0, 0, 0, 0}; //in terms of AND/OR gates - - std::vector next_pmux_y_ports, pmux_y_ports(costs.begin(), costs.begin() + num_versions); - for (auto i = 0; pmux_y_ports.size() > 1; ++i) { - for (auto j = 0; j+1 < GetSize(pmux_y_ports); j += 2) { - next_pmux_y_ports.emplace_back(module->Pmux(stringf("%s_mux_%d_%d", metamux_select.as_wire()->name.c_str(), i, j), pmux_y_ports[j], pmux_y_ports[j+1], metamux_select[GetSize(metamux_select) - 1 - i], metamux_select.as_wire()->get_src_attribute())); + if (opt_simplecostmodel) { + //The complex model is an area model, so a lower score should mean smaller. + //In this case, a nonzero hole metamux select value means less logic. + //Thus we should invert the ReduceOr over the metamux_select signal. + RTLIL::SigSpec pmux_select = module->ReduceOr(metamux_select.as_wire()->name.str() + "_nonzero", metamux_select); + return module->Pmux(NEW_ID, RTLIL::Const(1), RTLIL::Const(0), pmux_select, metamux_select.as_wire()->get_src_attribute()); + } else { + auto num_versions = opt_instrumentmore? 8 : 4; + auto select_width = log2(num_versions); + log_assert(metamux_select.as_wire()->width == select_width); + + std::vector costs = {5, 2, 2, 1, 0, 0, 0, 0}; //in terms of AND/OR gates + + std::vector next_pmux_y_ports, pmux_y_ports(costs.begin(), costs.begin() + num_versions); + for (auto i = 0; pmux_y_ports.size() > 1; ++i) { + for (auto j = 0; j+1 < GetSize(pmux_y_ports); j += 2) { + next_pmux_y_ports.emplace_back(module->Pmux(stringf("%s_mux_%d_%d", metamux_select.as_wire()->name.c_str(), i, j), pmux_y_ports[j], pmux_y_ports[j+1], metamux_select[GetSize(metamux_select) - 1 - i], metamux_select.as_wire()->get_src_attribute())); + } + if (GetSize(pmux_y_ports) % 2 == 1) + next_pmux_y_ports.push_back(pmux_y_ports[GetSize(pmux_y_ports) - 1]); + pmux_y_ports.swap(next_pmux_y_ports); + next_pmux_y_ports.clear(); } - if (GetSize(pmux_y_ports) % 2 == 1) - next_pmux_y_ports.push_back(pmux_y_ports[GetSize(pmux_y_ports) - 1]); - pmux_y_ports.swap(next_pmux_y_ports); - next_pmux_y_ports.clear(); - } - log_assert(pmux_y_ports.size() == 1); - return pmux_y_ports[0]; + log_assert(pmux_y_ports.size() == 1); + return pmux_y_ports[0]; + } } void create_glift_logic() { @@ -276,7 +292,7 @@ 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: + //Create a rough model of area by summing the (potentially simplified) "weight" score of each meta-mux select: if (!opt_nocostmodel) { std::vector meta_mux_select_sums; std::vector meta_mux_select_sums_buf; @@ -317,6 +333,7 @@ struct GliftPass : public Pass { opt_create_instrumented_model = false; opt_taintconstants = false; opt_keepoutputs = false; + opt_simplecostmodel = false; opt_nocostmodel = false; opt_instrumentmore = false; module = nullptr; @@ -328,7 +345,7 @@ struct GliftPass : public Pass { public: - GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise_model(false), opt_create_imprecise_model(false), opt_create_instrumented_model(false), opt_taintconstants(false), opt_keepoutputs(false), opt_nocostmodel(false), opt_instrumentmore(false), module(nullptr) { } + GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise_model(false), opt_create_imprecise_model(false), opt_create_instrumented_model(false), opt_taintconstants(false), opt_keepoutputs(false), opt_simplecostmodel(false), opt_nocostmodel(false), opt_instrumentmore(false), module(nullptr) { } void help() YS_OVERRIDE { @@ -388,6 +405,14 @@ struct GliftPass : public Pass { log(" alongside the orignal outputs.\n"); log(" (default: original module outputs are removed)\n"); log("\n"); + log(" -simple-cost-model\n"); + log(" Do not model logic area. Instead model the number of non-zero assignments to $anyconsts.\n"); + log(" Taint tracking logic versions vary in their size, but all reduced-precision versions are\n"); + log(" significantly smaller than the fully-precise version. A non-zero $anyconst assignment means\n"); + log(" that reduced-precision taint tracking logic was chosen for some gate.\n"); + log(" Only applicable in combination with `-create-instrumented-model`.\n"); + log(" (default: use a complex model and give that wire the \"keep\" and \"minimize\" attributes)\n"); + log("\n"); log(" -no-cost-model\n"); log(" Do not model taint tracking logic area and do not create a `__glift_weight` wire.\n"); log(" Only applicable in combination with `-create-instrumented-model`.\n"); -- cgit v1.2.3 From 20ad37172428ae12378f87540acab55c874530fe Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Fri, 19 Jun 2020 19:57:09 +0000 Subject: glift: Replace `YS_OVERRIDE` with `override`. --- passes/cmds/glift.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index eee1b2c79..26fdc4df7 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -347,7 +347,7 @@ struct GliftPass : public Pass { GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise_model(false), opt_create_imprecise_model(false), opt_create_instrumented_model(false), opt_taintconstants(false), opt_keepoutputs(false), opt_simplecostmodel(false), opt_nocostmodel(false), opt_instrumentmore(false), module(nullptr) { } - void help() YS_OVERRIDE + void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -433,7 +433,7 @@ struct GliftPass : public Pass { log("\n"); } - void execute(std::vector _args, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector _args, RTLIL::Design *design) override { log_header(design, "Executing GLIFT pass (creating and manipulating GLIFT models).\n"); -- cgit v1.2.3 From 209a123b9776fd28d73b64729eb815b2a6bfb774 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Sun, 21 Jun 2020 07:33:06 +0000 Subject: glift: Add initial hierarchy support. --- passes/cmds/glift.cc | 71 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 12 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 26fdc4df7..cc0e805a0 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -19,6 +19,7 @@ #include "kernel/register.h" #include "kernel/rtlil.h" +#include "kernel/utils.h" #include "kernel/log.h" USING_YOSYS_NAMESPACE @@ -36,6 +37,7 @@ struct GliftPass : public Pass { RTLIL::Module *module; const RTLIL::IdString cost_model_wire_name = ID(__glift_weight); + const RTLIL::IdString glift_attribute_name = ID(glift); void parse_args() { for (argidx = 1; argidx < args.size(); argidx++) { @@ -190,12 +192,15 @@ struct GliftPass : public Pass { } } - void create_glift_logic() { + void create_glift_logic(bool is_top_module) { + if (module->get_bool_attribute(glift_attribute_name)) + return; + std::vector connections(module->connections()); for(auto &cell : module->cells().to_vector()) { - if (!cell->type.in("$_AND_", "$_OR_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert")) { - log_cmd_error("Invalid cell type \"%s\" found. Module must be techmapped.\n", cell->type.c_str()); + if (!cell->type.in({"$_AND_", "$_OR_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { + log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type.c_str()); } if (cell->type.in("$_AND_", "$_OR_")) { const unsigned int A = 0, B = 1, Y = 2; @@ -278,13 +283,31 @@ struct GliftPass : public Pass { } else log_cmd_error("This is a bug (2).\n"); } + else if (module->design->module(cell->type) != nullptr) { + //User cell type + //This function is called on modules according to topological order, so we do not need to + //recurse to GLIFT model the child module. However, we need to augment the ports list + //with taint signals and connect the new ports to the corresponding taint signals. + RTLIL::Module *cell_module_def = module->design->module(cell->type); + dict orig_ports = cell->connections(); + log("Adding cell %s\n", cell_module_def->name.c_str()); + for (auto &it : orig_ports) { + RTLIL::SigSpec port = it.second; + RTLIL::SigSpec port_taint = get_corresponding_taint_signal(port); + + log_assert(port_taint.is_wire()); + log_assert(std::find(cell_module_def->ports.begin(), cell_module_def->ports.end(), port_taint.as_wire()->name) != cell_module_def->ports.end()); + cell->setPort(port_taint.as_wire()->name, port_taint); + } + } + else log_cmd_error("This is a bug (3).\n"); } //end foreach cell in cells for (auto &conn : connections) { RTLIL::SigSpec first = get_corresponding_taint_signal(conn.first); RTLIL::SigSpec second = get_corresponding_taint_signal(conn.second); - module->connect(get_corresponding_taint_signal(conn.first), get_corresponding_taint_signal(conn.second)); + module->connect(first, second); if(conn.second.is_wire() && conn.second.as_wire()->port_input) second.as_wire()->port_input = true; @@ -319,12 +342,13 @@ struct GliftPass : public Pass { for (auto &port_name : module->ports) { RTLIL::Wire *port = module->wire(port_name); log_assert(port != nullptr); - if (port->port_output && !opt_keepoutputs) + if (is_top_module && port->port_output && !opt_keepoutputs) port->port_output = false; } for (auto &output : new_taint_outputs) output->port_output = true; module->fixup_ports(); //we have some new taint signals in the module interface + module->set_bool_attribute(glift_attribute_name, true); } void reset() { @@ -442,15 +466,38 @@ struct GliftPass : public Pass { parse_args(); extra_args(args, argidx, design); - for (auto mod : design->selected_modules()) { - if (module) - log_cmd_error("Only one module may be selected for the glift pass! Flatten the design if necessary. (selected: %s and %s)\n", log_id(module), log_id(mod)); - module = mod; - } - if (module == nullptr) + if (GetSize(design->selected_modules()) == 0) log_cmd_error("Can't operate on an empty selection!\n"); - create_glift_logic(); + TopoSort> topo_modules; //cribbed from passes/techmap/flatten.cc + auto worklist = design->selected_modules(); + pool non_top_modules; + while (!worklist.empty()) { + RTLIL::Module *module = *(worklist.begin()); + worklist.erase(worklist.begin()); + topo_modules.node(module); + + for (auto cell : module->selected_cells()) { + RTLIL::Module *tpl = design->module(cell->type); + if (tpl != nullptr) { + if (topo_modules.database.count(tpl) == 0) + worklist.push_back(tpl); + topo_modules.edge(tpl, module); + non_top_modules.insert(cell->type); + } + } + } + + if (!topo_modules.sort()) + log_cmd_error("Cannot handle recursive module instantiations.\n"); + + for (auto i = 0; i < GetSize(topo_modules.sorted); ++i) { + new_taint_outputs.clear(); + meta_mux_selects.clear(); + module = topo_modules.sorted[i]; + + create_glift_logic(!non_top_modules[module->name]); + } } } GliftPass; -- cgit v1.2.3 From 23defc6fe9382b2efcfc0a855655f0d235c597b5 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Mon, 22 Jun 2020 00:22:12 +0000 Subject: glift: Add support for $_XOR_ and $_XNOR_ cells. --- passes/cmds/glift.cc | 94 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 79 insertions(+), 15 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index cc0e805a0..f890a80bb 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -33,7 +33,7 @@ struct GliftPass : public Pass { std::vector args; std::vector::size_type argidx; std::vector new_taint_outputs; - std::vector meta_mux_selects; + std::vector> meta_mux_selects; RTLIL::Module *module; const RTLIL::IdString cost_model_wire_name = ID(__glift_weight); @@ -140,7 +140,7 @@ struct GliftPass : public Pass { } void add_imprecise_GLIFT_logic_3(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { - //AKA AN2_SH5 or OR2_SH5 + //AKA AN2_SH5 or OR2_SH5 or XR2_SH2 module->addOr(cell->name.str() + "_t_4_1", port_a_taint, port_b_taint, port_y_taint, false, cell->get_src_attribute()); } @@ -160,7 +160,7 @@ struct GliftPass : public Pass { module->connect(port_y_taint, RTLIL::Const(0, 1)); } - RTLIL::SigSpec score_metamux_select(const RTLIL::SigSpec &metamux_select) { + RTLIL::SigSpec score_metamux_select(const RTLIL::SigSpec &metamux_select, const RTLIL::IdString celltype) { log_assert(metamux_select.is_wire()); if (opt_simplecostmodel) { @@ -170,13 +170,21 @@ struct GliftPass : public Pass { RTLIL::SigSpec pmux_select = module->ReduceOr(metamux_select.as_wire()->name.str() + "_nonzero", metamux_select); return module->Pmux(NEW_ID, RTLIL::Const(1), RTLIL::Const(0), pmux_select, metamux_select.as_wire()->get_src_attribute()); } else { - auto num_versions = opt_instrumentmore? 8 : 4; - auto select_width = log2(num_versions); - log_assert(metamux_select.as_wire()->width == select_width); - - std::vector costs = {5, 2, 2, 1, 0, 0, 0, 0}; //in terms of AND/OR gates + auto select_width = metamux_select.as_wire()->width; + + std::vector costs; + if (celltype == ID(_AND_) || celltype == ID(_OR_)) { + costs = {5, 2, 2, 1, 0, 0, 0, 0}; + log_assert(select_width == 2 || select_width == 3); + log_assert(opt_instrumentmore || select_width == 2); + log_assert(!opt_instrumentmore || select_width == 3); + } + else if (celltype == ID(_XOR_) || celltype == ID(_XNOR_)) { + costs = {1, 0, 0, 0}; + log_assert(select_width == 2); + } - std::vector next_pmux_y_ports, pmux_y_ports(costs.begin(), costs.begin() + num_versions); + std::vector next_pmux_y_ports, pmux_y_ports(costs.begin(), costs.begin() + exp2(select_width)); for (auto i = 0; pmux_y_ports.size() > 1; ++i) { for (auto j = 0; j+1 < GetSize(pmux_y_ports); j += 2) { next_pmux_y_ports.emplace_back(module->Pmux(stringf("%s_mux_%d_%d", metamux_select.as_wire()->name.c_str(), i, j), pmux_y_ports[j], pmux_y_ports[j+1], metamux_select[GetSize(metamux_select) - 1 - i], metamux_select.as_wire()->get_src_attribute())); @@ -199,7 +207,7 @@ struct GliftPass : public Pass { std::vector connections(module->connections()); for(auto &cell : module->cells().to_vector()) { - if (!cell->type.in({"$_AND_", "$_OR_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { + if (!cell->type.in({"$_AND_", "$_OR_", "$_XOR_", "$_XNOR_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type.c_str()); } if (cell->type.in("$_AND_", "$_OR_")) { @@ -249,7 +257,7 @@ struct GliftPass : public Pass { auto select_width = log2(num_versions); log_assert(exp2(select_width) == num_versions); RTLIL::SigSpec meta_mux_select(module->addWire(cell->name.str() + "_sel", select_width)); - meta_mux_selects.push_back(meta_mux_select); + meta_mux_selects.push_back(make_pair(meta_mux_select, cell->type)); module->connect(meta_mux_select, module->Anyconst(cell->name.str() + "_hole", select_width, cell->get_src_attribute())); std::vector next_meta_mux_y_ports, meta_mux_y_ports(taint_version); @@ -267,6 +275,62 @@ struct GliftPass : public Pass { } else log_cmd_error("This is a bug (1).\n"); } + else if (cell->type.in("$_XOR_", "$_XNOR_")) { + const unsigned int A = 0, B = 1, Y = 2; + const unsigned int NUM_PORTS = 3; + RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::B), cell->getPort(ID::Y)}; + RTLIL::SigSpec port_taints[NUM_PORTS]; + + if (ports[A].size() != 1 || ports[B].size() != 1 || ports[Y].size() != 1) + log_cmd_error("Multi-bit signal found. Run `splitnets` first.\n"); + for (unsigned int i = 0; i < NUM_PORTS; ++i) + port_taints[i] = get_corresponding_taint_signal(ports[i]); + + if (opt_create_precise_model || opt_create_imprecise_model) + add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], port_taints[Y]); + else if (opt_create_instrumented_model) { + std::vector taint_version; + int num_versions = 4; + auto select_width = log2(num_versions); + log_assert(exp2(select_width) == num_versions); + + for (auto i = 1; i <= num_versions; ++i) + taint_version.emplace_back(RTLIL::SigSpec(module->addWire(stringf("%s_y%d", cell->name.c_str(), i), 1))); + + for (auto i = 0; i < num_versions; ++i) { + switch(i) { + case 0: add_imprecise_GLIFT_logic_3(cell, port_taints[A], port_taints[B], taint_version[i]); + break; + case 1: add_imprecise_GLIFT_logic_4(port_taints[A], taint_version[i]); + break; + case 2: add_imprecise_GLIFT_logic_5(port_taints[B], taint_version[i]); + break; + case 3: add_imprecise_GLIFT_logic_6(taint_version[i]); + break; + default: log_assert(false); + } + } + + RTLIL::SigSpec meta_mux_select(module->addWire(cell->name.str() + "_sel", select_width)); + meta_mux_selects.push_back(make_pair(meta_mux_select, cell->type)); + module->connect(meta_mux_select, module->Anyconst(cell->name.str() + "_hole", select_width, cell->get_src_attribute())); + + std::vector next_meta_mux_y_ports, meta_mux_y_ports(taint_version); + for (auto i = 0; meta_mux_y_ports.size() > 1; ++i) { + for (auto j = 0; j+1 < GetSize(meta_mux_y_ports); j += 2) { + next_meta_mux_y_ports.emplace_back(module->Mux(stringf("%s_mux_%d_%d", cell->name.c_str(), i, j), meta_mux_y_ports[j], meta_mux_y_ports[j+1], meta_mux_select[GetSize(meta_mux_select) - 1 - i])); + } + if (GetSize(meta_mux_y_ports) % 2 == 1) + next_meta_mux_y_ports.push_back(meta_mux_y_ports[GetSize(meta_mux_y_ports) - 1]); + meta_mux_y_ports.swap(next_meta_mux_y_ports); + next_meta_mux_y_ports.clear(); + } + log_assert(meta_mux_y_ports.size() == 1); + module->connect(port_taints[Y], meta_mux_y_ports[0]); + } + else log_cmd_error("This is a bug (2).\n"); + + } else if (cell->type.in("$_NOT_")) { const unsigned int A = 0, Y = 1; const unsigned int NUM_PORTS = 2; @@ -281,7 +345,7 @@ struct GliftPass : public Pass { if (cell->type == "$_NOT_") { module->connect(port_taints[Y], port_taints[A]); } - else log_cmd_error("This is a bug (2).\n"); + else log_cmd_error("This is a bug (3).\n"); } else if (module->design->module(cell->type) != nullptr) { //User cell type @@ -300,7 +364,7 @@ struct GliftPass : public Pass { cell->setPort(port_taint.as_wire()->name, port_taint); } } - else log_cmd_error("This is a bug (3).\n"); + else log_cmd_error("This is a bug (4).\n"); } //end foreach cell in cells for (auto &conn : connections) { @@ -319,8 +383,8 @@ struct GliftPass : public Pass { if (!opt_nocostmodel) { std::vector meta_mux_select_sums; std::vector meta_mux_select_sums_buf; - for (auto &wire : meta_mux_selects) { - meta_mux_select_sums.emplace_back(score_metamux_select(wire)); + for (auto &it : meta_mux_selects) { + meta_mux_select_sums.emplace_back(score_metamux_select(it.first, it.second)); } for (unsigned int i = 0; meta_mux_select_sums.size() > 1; ) { meta_mux_select_sums_buf.clear(); -- cgit v1.2.3 From 8cb1a86c23a8d9abbaadc1e7400018a593e2e818 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Mon, 22 Jun 2020 05:54:14 +0000 Subject: glift: Add support for $_MUX_ and $_NMUX_ cells. --- passes/cmds/glift.cc | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'passes/cmds') diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index f890a80bb..d6d873e01 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -160,6 +160,26 @@ struct GliftPass : public Pass { module->connect(port_y_taint, RTLIL::Const(0, 1)); } + void add_precise_GLIFT_mux(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_s, RTLIL::SigSpec &port_s_taint, RTLIL::SigSpec &port_y_taint) { + //S&At | ~S&Bt | ~A&B&St | A&~B&St | At&St | Bt&St + RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_4_1", port_a, false, cell->get_src_attribute()); + RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_4_2", port_b, false, cell->get_src_attribute()); + RTLIL::SigSpec n_port_s = module->LogicNot(cell->name.str() + "_t_4_3", port_s, false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_4_4", port_s, port_a_taint, false, cell->get_src_attribute()); + auto subexpr2 = module->And(cell->name.str() + "_t_4_5", n_port_s, port_b_taint, false, cell->get_src_attribute()); + auto subexpr3 = module->And(cell->name.str() + "_t_4_6", n_port_a, port_b, false, cell->get_src_attribute()); + auto subexpr4 = module->And(cell->name.str() + "_t_4_7", subexpr3, port_s_taint, false, cell->get_src_attribute()); + auto subexpr5 = module->And(cell->name.str() + "_t_4_8", port_a, n_port_b, false, cell->get_src_attribute()); + auto subexpr6 = module->And(cell->name.str() + "_t_4_9", subexpr5, port_s_taint, false, cell->get_src_attribute()); + auto subexpr7 = module->And(cell->name.str() + "_t_4_10", port_a_taint, port_s_taint, false, cell->get_src_attribute()); + auto subexpr8 = module->And(cell->name.str() + "_t_4_11", port_b_taint, port_s_taint, false, cell->get_src_attribute()); + auto subexpr9 = module->Or(cell->name.str() + "_t_4_12", subexpr1, subexpr2, false, cell->get_src_attribute()); + auto subexpr10 = module->Or(cell->name.str() + "_t_4_13", subexpr4, subexpr6, false, cell->get_src_attribute()); + auto subexpr11 = module->Or(cell->name.str() + "_t_4_14", subexpr7, subexpr8, false, cell->get_src_attribute()); + auto subexpr12 = module->Or(cell->name.str() + "_t_4_15", subexpr9, subexpr10, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_4_16", subexpr11, subexpr12, port_y_taint, false, cell->get_src_attribute()); + } + RTLIL::SigSpec score_metamux_select(const RTLIL::SigSpec &metamux_select, const RTLIL::IdString celltype) { log_assert(metamux_select.is_wire()); @@ -207,7 +227,7 @@ struct GliftPass : public Pass { std::vector connections(module->connections()); for(auto &cell : module->cells().to_vector()) { - if (!cell->type.in({"$_AND_", "$_OR_", "$_XOR_", "$_XNOR_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { + if (!cell->type.in({"$_AND_", "$_OR_", "$_XOR_", "$_XNOR_", "$_MUX_", "$_NMUX_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type.c_str()); } if (cell->type.in("$_AND_", "$_OR_")) { @@ -331,6 +351,19 @@ struct GliftPass : public Pass { else log_cmd_error("This is a bug (2).\n"); } + else if (cell->type.in("$_MUX_", "$_NMUX_")) { + const unsigned int A = 0, B = 1, S = 2, Y = 3; + const unsigned int NUM_PORTS = 4; + RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::B), cell->getPort(ID::S), cell->getPort(ID::Y)}; + RTLIL::SigSpec port_taints[NUM_PORTS]; + + if (ports[A].size() != 1 || ports[B].size() != 1 || ports[S].size() != 1 || ports[Y].size() != 1) + log_cmd_error("Multi-bit signal found. Run `splitnets` first.\n"); + for (unsigned int i = 0; i < NUM_PORTS; ++i) + port_taints[i] = get_corresponding_taint_signal(ports[i]); + + add_precise_GLIFT_mux(cell, ports[A], port_taints[A], ports[B], port_taints[B], ports[S], port_taints[S], port_taints[Y]); + } else if (cell->type.in("$_NOT_")) { const unsigned int A = 0, Y = 1; const unsigned int NUM_PORTS = 2; -- cgit v1.2.3 From 3eb2593876b3778d158b1955aa5a2b4bf40aab5a Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Mon, 22 Jun 2020 06:03:36 +0000 Subject: glift: Add support for $_NAND_ and $_NOR_ cells. --- passes/cmds/glift.cc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index d6d873e01..0968da71e 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -116,10 +116,11 @@ struct GliftPass : public Pass { void add_precise_GLIFT_logic(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { //AKA AN2_SH2 or OR2_SH2 + bool is_and = cell->type.in("$_AND_", "$_NAND_"); RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_1_1", port_a, false, cell->get_src_attribute()); RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_1_2", port_b, false, cell->get_src_attribute()); - auto subexpr1 = module->And(cell->name.str() + "_t_1_3", (cell->type == "$_AND_")? port_a : n_port_a, port_b_taint, false, cell->get_src_attribute()); - auto subexpr2 = module->And(cell->name.str() + "_t_1_4", (cell->type == "$_AND_")? port_b : n_port_b, port_a_taint, false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_1_3", is_and? port_a : n_port_a, port_b_taint, false, cell->get_src_attribute()); + auto subexpr2 = module->And(cell->name.str() + "_t_1_4", is_and? port_b : n_port_b, port_a_taint, false, cell->get_src_attribute()); auto subexpr3 = module->And(cell->name.str() + "_t_1_5", port_a_taint, port_b_taint, false, cell->get_src_attribute()); auto subexpr4 = module->Or(cell->name.str() + "_t_1_6", subexpr1, subexpr2, false, cell->get_src_attribute()); module->addOr(cell->name.str() + "_t_1_7", subexpr4, subexpr3, port_y_taint, false, cell->get_src_attribute()); @@ -127,16 +128,18 @@ struct GliftPass : public Pass { void add_imprecise_GLIFT_logic_1(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { //AKA AN2_SH3 or OR2_SH3 + bool is_and = cell->type.in("$_AND_", "$_NAND_"); RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_2_1", port_a, false, cell->get_src_attribute()); - auto subexpr1 = module->And(cell->name.str() + "_t_2_2", (cell->type == "$_AND_")? port_b : n_port_a, (cell->type == "$_AND_")? port_a_taint : port_b_taint, false, cell->get_src_attribute()); - module->addOr(cell->name.str() + "_t_2_3", (cell->type == "$_AND_")? port_b_taint : port_a_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_2_2", is_and? port_b : n_port_a, is_and? port_a_taint : port_b_taint, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_2_3", is_and? port_b_taint : port_a_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); } void add_imprecise_GLIFT_logic_2(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { //AKA AN2_SH4 or OR2_SH4 + bool is_and = cell->type.in("$_AND_", "$_NAND_"); RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_3_1", port_b, false, cell->get_src_attribute()); - auto subexpr1 = module->And(cell->name.str() + "_t_3_2", (cell->type == "$_AND_")? port_a : n_port_b, (cell->type == "$_AND_")? port_b_taint : port_a_taint, false, cell->get_src_attribute()); - module->addOr(cell->name.str() + "_t_3_3", (cell->type == "$_AND_")? port_a_taint : port_b_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); + auto subexpr1 = module->And(cell->name.str() + "_t_3_2", is_and? port_a : n_port_b, is_and? port_b_taint : port_a_taint, false, cell->get_src_attribute()); + module->addOr(cell->name.str() + "_t_3_3", is_and? port_a_taint : port_b_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); } void add_imprecise_GLIFT_logic_3(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { @@ -227,10 +230,10 @@ struct GliftPass : public Pass { std::vector connections(module->connections()); for(auto &cell : module->cells().to_vector()) { - if (!cell->type.in({"$_AND_", "$_OR_", "$_XOR_", "$_XNOR_", "$_MUX_", "$_NMUX_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { + if (!cell->type.in({"$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_MUX_", "$_NMUX_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type.c_str()); } - if (cell->type.in("$_AND_", "$_OR_")) { + if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_")) { const unsigned int A = 0, B = 1, Y = 2; const unsigned int NUM_PORTS = 3; RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::B), cell->getPort(ID::Y)}; -- cgit v1.2.3 From eda1af73c47fd24c14ac75e01bdc4e1a37194fb4 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Mon, 22 Jun 2020 18:41:01 +0000 Subject: glift: Use worker pattern. --- passes/cmds/glift.cc | 155 +++++++++++++++++++++++++-------------------------- 1 file changed, 75 insertions(+), 80 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 0968da71e..127abd7af 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -25,65 +25,19 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -struct GliftPass : public Pass { - private: - - bool opt_create_precise_model, opt_create_imprecise_model, opt_create_instrumented_model; - bool opt_taintconstants, opt_keepoutputs, opt_simplecostmodel, opt_nocostmodel, opt_instrumentmore; - std::vector args; - std::vector::size_type argidx; +struct GliftWorker { +private: + bool is_top_module = false; + bool opt_create_precise_model = false, opt_create_imprecise_model = false, opt_create_instrumented_model = false; + bool opt_taintconstants = false, opt_keepoutputs = false, opt_simplecostmodel = false, opt_nocostmodel = false; + bool opt_instrumentmore = false; std::vector new_taint_outputs; std::vector> meta_mux_selects; - RTLIL::Module *module; + RTLIL::Module *module = nullptr; const RTLIL::IdString cost_model_wire_name = ID(__glift_weight); const RTLIL::IdString glift_attribute_name = ID(glift); - void parse_args() { - for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-create-precise-model") { - opt_create_precise_model = true; - continue; - } - if (args[argidx] == "-create-imprecise-model") { - opt_create_imprecise_model = true; - continue; - } - if (args[argidx] == "-create-instrumented-model") { - opt_create_instrumented_model = true; - continue; - } - if (args[argidx] == "-taint-constants") { - opt_taintconstants = true; - continue; - } - if (args[argidx] == "-keep-outputs") { - opt_keepoutputs = true; - continue; - } - if (args[argidx] == "-simple-cost-model") { - opt_simplecostmodel = true; - continue; - } - if (args[argidx] == "-no-cost-model") { - opt_nocostmodel = true; - continue; - } - if (args[argidx] == "-instrument-more") { - opt_instrumentmore = true; - continue; - } - break; - } - if(!opt_create_precise_model && !opt_create_imprecise_model && !opt_create_instrumented_model) - log_cmd_error("No command provided. See help for usage.\n"); - if(static_cast(opt_create_precise_model) + static_cast(opt_create_imprecise_model) + static_cast(opt_create_instrumented_model) != 1) - log_cmd_error("Only one command may be specified. See help for usage.\n"); - if(opt_simplecostmodel && opt_nocostmodel) - log_cmd_error("Only one of `-simple-cost-model` and `-no-cost-model` may be specified. See help for usage.\n"); - if((opt_simplecostmodel || opt_nocostmodel) && !opt_create_instrumented_model) - log_cmd_error("Options `-simple-cost-model` and `-no-cost-model` may only be used with `-create-instrumented-model`. See help for usage.\n"); - } RTLIL::SigSpec get_corresponding_taint_signal(RTLIL::SigSpec sig) { RTLIL::SigSpec ret; @@ -223,7 +177,7 @@ struct GliftPass : public Pass { } } - void create_glift_logic(bool is_top_module) { + void create_glift_logic() { if (module->get_bool_attribute(glift_attribute_name)) return; @@ -451,25 +405,25 @@ struct GliftPass : public Pass { module->set_bool_attribute(glift_attribute_name, true); } - void reset() { - opt_create_precise_model = false; - opt_create_imprecise_model = false; - opt_create_instrumented_model = false; - opt_taintconstants = false; - opt_keepoutputs = false; - opt_simplecostmodel = false; - opt_nocostmodel = false; - opt_instrumentmore = false; - module = nullptr; - args.clear(); - argidx = 0; - new_taint_outputs.clear(); - meta_mux_selects.clear(); +public: + GliftWorker(RTLIL::Module *_module, bool _is_top_module, bool _opt_create_precise_model, bool _opt_create_imprecise_model, bool _opt_create_instrumented_model, bool _opt_taintconstants, bool _opt_keepoutputs, bool _opt_simplecostmodel, bool _opt_nocostmodel, bool _opt_instrumentmore) { + module = _module; + is_top_module = _is_top_module; + opt_create_precise_model = _opt_create_precise_model; + opt_create_imprecise_model = _opt_create_imprecise_model; + opt_create_instrumented_model = _opt_create_instrumented_model; + opt_taintconstants = _opt_taintconstants; + opt_keepoutputs = _opt_keepoutputs; + opt_simplecostmodel = _opt_simplecostmodel; + opt_nocostmodel = _opt_nocostmodel; + opt_instrumentmore = _opt_instrumentmore; + + create_glift_logic(); } +}; - public: - - GliftPass() : Pass("glift", "create GLIFT models and optimization problems"), opt_create_precise_model(false), opt_create_imprecise_model(false), opt_create_instrumented_model(false), opt_taintconstants(false), opt_keepoutputs(false), opt_simplecostmodel(false), opt_nocostmodel(false), opt_instrumentmore(false), module(nullptr) { } +struct GliftPass : public Pass { + GliftPass() : Pass("glift", "create GLIFT models and optimization problems") {} void help() override { @@ -557,13 +511,57 @@ struct GliftPass : public Pass { log("\n"); } - void execute(std::vector _args, RTLIL::Design *design) override + void execute(std::vector args, RTLIL::Design *design) override { + bool opt_create_precise_model = false, opt_create_imprecise_model = false, opt_create_instrumented_model = false; + bool opt_taintconstants = false, opt_keepoutputs = false, opt_simplecostmodel = false, opt_nocostmodel = false; + bool opt_instrumentmore = false; log_header(design, "Executing GLIFT pass (creating and manipulating GLIFT models).\n"); + std::vector::size_type argidx; - reset(); - args = _args; - parse_args(); + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-create-precise-model") { + opt_create_precise_model = true; + continue; + } + if (args[argidx] == "-create-imprecise-model") { + opt_create_imprecise_model = true; + continue; + } + if (args[argidx] == "-create-instrumented-model") { + opt_create_instrumented_model = true; + continue; + } + if (args[argidx] == "-taint-constants") { + opt_taintconstants = true; + continue; + } + if (args[argidx] == "-keep-outputs") { + opt_keepoutputs = true; + continue; + } + if (args[argidx] == "-simple-cost-model") { + opt_simplecostmodel = true; + continue; + } + if (args[argidx] == "-no-cost-model") { + opt_nocostmodel = true; + continue; + } + if (args[argidx] == "-instrument-more") { + opt_instrumentmore = true; + continue; + } + break; + } + if(!opt_create_precise_model && !opt_create_imprecise_model && !opt_create_instrumented_model) + log_cmd_error("No command provided. See help for usage.\n"); + if(static_cast(opt_create_precise_model) + static_cast(opt_create_imprecise_model) + static_cast(opt_create_instrumented_model) != 1) + log_cmd_error("Only one command may be specified. See help for usage.\n"); + if(opt_simplecostmodel && opt_nocostmodel) + log_cmd_error("Only one of `-simple-cost-model` and `-no-cost-model` may be specified. See help for usage.\n"); + if((opt_simplecostmodel || opt_nocostmodel) && !opt_create_instrumented_model) + log_cmd_error("Options `-simple-cost-model` and `-no-cost-model` may only be used with `-create-instrumented-model`. See help for usage.\n"); extra_args(args, argidx, design); if (GetSize(design->selected_modules()) == 0) @@ -592,11 +590,8 @@ struct GliftPass : public Pass { log_cmd_error("Cannot handle recursive module instantiations.\n"); for (auto i = 0; i < GetSize(topo_modules.sorted); ++i) { - new_taint_outputs.clear(); - meta_mux_selects.clear(); - module = topo_modules.sorted[i]; - - create_glift_logic(!non_top_modules[module->name]); + RTLIL::Module *module = topo_modules.sorted[i]; + GliftWorker(module, !non_top_modules[module->name], opt_create_precise_model, opt_create_imprecise_model, opt_create_instrumented_model, opt_taintconstants, opt_keepoutputs, opt_simplecostmodel, opt_nocostmodel, opt_instrumentmore); } } } GliftPass; -- cgit v1.2.3 From bbfa2d65fa1a89765568ac3afa7ca65b67d24bf2 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Mon, 22 Jun 2020 18:50:29 +0000 Subject: glift: Use ID() rather than string literals. --- passes/cmds/glift.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/glift.cc b/passes/cmds/glift.cc index 127abd7af..b398c3e04 100644 --- a/passes/cmds/glift.cc +++ b/passes/cmds/glift.cc @@ -70,7 +70,7 @@ private: void add_precise_GLIFT_logic(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { //AKA AN2_SH2 or OR2_SH2 - bool is_and = cell->type.in("$_AND_", "$_NAND_"); + bool is_and = cell->type.in(ID($_AND_), ID($_NAND_)); RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_1_1", port_a, false, cell->get_src_attribute()); RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_1_2", port_b, false, cell->get_src_attribute()); auto subexpr1 = module->And(cell->name.str() + "_t_1_3", is_and? port_a : n_port_a, port_b_taint, false, cell->get_src_attribute()); @@ -82,7 +82,7 @@ private: void add_imprecise_GLIFT_logic_1(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { //AKA AN2_SH3 or OR2_SH3 - bool is_and = cell->type.in("$_AND_", "$_NAND_"); + bool is_and = cell->type.in(ID($_AND_), ID($_NAND_)); RTLIL::SigSpec n_port_a = module->LogicNot(cell->name.str() + "_t_2_1", port_a, false, cell->get_src_attribute()); auto subexpr1 = module->And(cell->name.str() + "_t_2_2", is_and? port_b : n_port_a, is_and? port_a_taint : port_b_taint, false, cell->get_src_attribute()); module->addOr(cell->name.str() + "_t_2_3", is_and? port_b_taint : port_a_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); @@ -90,7 +90,7 @@ private: void add_imprecise_GLIFT_logic_2(const RTLIL::Cell *cell, RTLIL::SigSpec &port_a, RTLIL::SigSpec &port_a_taint, RTLIL::SigSpec &port_b, RTLIL::SigSpec &port_b_taint, RTLIL::SigSpec &port_y_taint) { //AKA AN2_SH4 or OR2_SH4 - bool is_and = cell->type.in("$_AND_", "$_NAND_"); + bool is_and = cell->type.in(ID($_AND_), ID($_NAND_)); RTLIL::SigSpec n_port_b = module->LogicNot(cell->name.str() + "_t_3_1", port_b, false, cell->get_src_attribute()); auto subexpr1 = module->And(cell->name.str() + "_t_3_2", is_and? port_a : n_port_b, is_and? port_b_taint : port_a_taint, false, cell->get_src_attribute()); module->addOr(cell->name.str() + "_t_3_3", is_and? port_a_taint : port_b_taint, subexpr1, port_y_taint, false, cell->get_src_attribute()); @@ -150,13 +150,13 @@ private: auto select_width = metamux_select.as_wire()->width; std::vector costs; - if (celltype == ID(_AND_) || celltype == ID(_OR_)) { + if (celltype == ID($_AND_) || celltype == ID($_OR_)) { costs = {5, 2, 2, 1, 0, 0, 0, 0}; log_assert(select_width == 2 || select_width == 3); log_assert(opt_instrumentmore || select_width == 2); log_assert(!opt_instrumentmore || select_width == 3); } - else if (celltype == ID(_XOR_) || celltype == ID(_XNOR_)) { + else if (celltype == ID($_XOR_) || celltype == ID($_XNOR_)) { costs = {1, 0, 0, 0}; log_assert(select_width == 2); } @@ -184,10 +184,10 @@ private: std::vector connections(module->connections()); for(auto &cell : module->cells().to_vector()) { - if (!cell->type.in({"$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_MUX_", "$_NMUX_", "$_NOT_", "$anyconst", "$allconst", "$assume", "$assert"}) && module->design->module(cell->type) == nullptr) { + if (!cell->type.in({ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_MUX_), ID($_NMUX_), ID($_NOT_), ID($anyconst), ID($allconst), ID($assume), ID($assert)}) && module->design->module(cell->type) == nullptr) { log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type.c_str()); } - if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_")) { + if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_))) { const unsigned int A = 0, B = 1, Y = 2; const unsigned int NUM_PORTS = 3; RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::B), cell->getPort(ID::Y)}; @@ -252,7 +252,7 @@ private: } else log_cmd_error("This is a bug (1).\n"); } - else if (cell->type.in("$_XOR_", "$_XNOR_")) { + else if (cell->type.in(ID($_XOR_), ID($_XNOR_))) { const unsigned int A = 0, B = 1, Y = 2; const unsigned int NUM_PORTS = 3; RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::B), cell->getPort(ID::Y)}; @@ -308,7 +308,7 @@ private: else log_cmd_error("This is a bug (2).\n"); } - else if (cell->type.in("$_MUX_", "$_NMUX_")) { + else if (cell->type.in(ID($_MUX_), ID($_NMUX_))) { const unsigned int A = 0, B = 1, S = 2, Y = 3; const unsigned int NUM_PORTS = 4; RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::B), cell->getPort(ID::S), cell->getPort(ID::Y)}; @@ -321,7 +321,7 @@ private: add_precise_GLIFT_mux(cell, ports[A], port_taints[A], ports[B], port_taints[B], ports[S], port_taints[S], port_taints[Y]); } - else if (cell->type.in("$_NOT_")) { + else if (cell->type.in(ID($_NOT_))) { const unsigned int A = 0, Y = 1; const unsigned int NUM_PORTS = 2; RTLIL::SigSpec ports[NUM_PORTS] = {cell->getPort(ID::A), cell->getPort(ID::Y)}; @@ -332,7 +332,7 @@ private: for (unsigned int i = 0; i < NUM_PORTS; ++i) port_taints[i] = get_corresponding_taint_signal(ports[i]); - if (cell->type == "$_NOT_") { + if (cell->type == ID($_NOT_)) { module->connect(port_taints[Y], port_taints[A]); } else log_cmd_error("This is a bug (3).\n"); -- cgit v1.2.3 From 4e03865d5bf3fafe0bd3735c88431675d53d2663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 23 Feb 2021 00:21:46 +0100 Subject: Add support for memory writes in processes. --- passes/cmds/bugpoint.cc | 17 +++++++++++++++++ passes/cmds/check.cc | 8 ++++++++ passes/cmds/show.cc | 5 +++++ 3 files changed, 30 insertions(+) (limited to 'passes/cmds') diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index da81e7f09..40207b1fc 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -339,6 +339,23 @@ struct BugpointPass : public Pass { return design_copy; } } + int i = 0; + for (auto it = sy->mem_write_actions.begin(); it != sy->mem_write_actions.end(); ++it, ++i) + { + if (index++ == seed) + { + log_header(design, "Trying to remove sync %s memwr %s %s %s %s in %s.%s.\n", log_signal(sy->signal), log_id(it->memid), log_signal(it->address), log_signal(it->data), log_signal(it->enable), log_id(mod), log_id(pr.first)); + sy->mem_write_actions.erase(it); + // Remove the bit for removed action from other actions' priority masks. + for (auto it2 = sy->mem_write_actions.begin(); it2 != sy->mem_write_actions.end(); ++it2) { + auto &mask = it2->priority_mask; + if (GetSize(mask) > i) { + mask.bits.erase(mask.bits.begin() + i); + } + } + return design_copy; + } + } } } } diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index 36febb98a..b502b0788 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -141,6 +141,14 @@ struct CheckPass : public Pass { for (auto bit : sigmap(action.second)) if (bit.wire) used_wires.insert(bit); } + for (auto memwr : sync->mem_write_actions) { + for (auto bit : sigmap(memwr.address)) + if (bit.wire) used_wires.insert(bit); + for (auto bit : sigmap(memwr.data)) + if (bit.wire) used_wires.insert(bit); + for (auto bit : sigmap(memwr.enable)) + if (bit.wire) used_wires.insert(bit); + } } } diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 0c96f8c5d..a389c3179 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -339,6 +339,11 @@ struct ShowWorker { input_signals.insert(obj->signal); collect_proc_signals(obj->actions, input_signals, output_signals); + for (auto it : obj->mem_write_actions) { + input_signals.insert(it.address); + input_signals.insert(it.data); + input_signals.insert(it.enable); + } } void collect_proc_signals(RTLIL::Process *obj, std::set &input_signals, std::set &output_signals) -- cgit v1.2.3 From dd6d34f461910a120ac95c485fe34cca6485b95e Mon Sep 17 00:00:00 2001 From: gatecat Date: Wed, 17 Mar 2021 12:06:09 +0000 Subject: blackbox: Include whiteboxed modules Signed-off-by: gatecat --- passes/cmds/blackbox.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'passes/cmds') diff --git a/passes/cmds/blackbox.cc b/passes/cmds/blackbox.cc index 08a635514..fca91852c 100644 --- a/passes/cmds/blackbox.cc +++ b/passes/cmds/blackbox.cc @@ -46,10 +46,11 @@ struct BlackboxPass : public Pass { } extra_args(args, argidx, design); - for (auto module : design->selected_whole_modules_warn()) + for (auto module : design->selected_whole_modules_warn(true)) { module->makeblackbox(); module->set_bool_attribute(ID::blackbox); + module->set_bool_attribute(ID::whitebox, false); } } } BlackboxPass; -- cgit v1.2.3 From c8b45a4a826efe88e17928b3d6f526dc2866312a Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 16 Mar 2021 10:54:22 -0400 Subject: bugpoint: add runner option --- passes/cmds/bugpoint.cc | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 40207b1fc..70c002c44 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -87,9 +87,12 @@ struct BugpointPass : public Pass { log(" -updates\n"); log(" try to remove process updates from syncs.\n"); log("\n"); + log(" -runner \"\"\n"); + log(" child process wrapping command, e.g., \"timeout 30\", or valgrind.\n"); + log("\n"); } - bool run_yosys(RTLIL::Design *design, string yosys_cmd, string yosys_arg) + bool run_yosys(RTLIL::Design *design, string runner, string yosys_cmd, string yosys_arg) { design->sort(); @@ -97,7 +100,7 @@ struct BugpointPass : public Pass { RTLIL_BACKEND::dump_design(f, design, /*only_selected=*/false, /*flag_m=*/true, /*flag_n=*/false); f.close(); - string yosys_cmdline = stringf("%s -qq -L bugpoint-case.log %s bugpoint-case.il", yosys_cmd.c_str(), yosys_arg.c_str()); + string yosys_cmdline = stringf("%s %s -qq -L bugpoint-case.log %s bugpoint-case.il", runner.c_str(), yosys_cmd.c_str(), yosys_arg.c_str()); return run_command(yosys_cmdline) == 0; } @@ -394,7 +397,7 @@ struct BugpointPass : public Pass { void execute(std::vector args, RTLIL::Design *design) override { - string yosys_cmd = "yosys", yosys_arg, grep; + string yosys_cmd = "yosys", yosys_arg, grep, runner; bool fast = false, clean = false; bool modules = false, ports = false, cells = false, connections = false, processes = false, assigns = false, updates = false, wires = false, has_part = false; @@ -472,6 +475,14 @@ struct BugpointPass : public Pass { has_part = true; continue; } + if (args[argidx] == "-runner" && argidx + 1 < args.size()) { + runner = args[++argidx]; + if (runner.size() && runner.at(0) == '"') { + log_assert(runner.back() == '"'); + runner = runner.substr(1, runner.size() - 2); + } + continue; + } break; } extra_args(args, argidx, design); @@ -495,7 +506,7 @@ struct BugpointPass : public Pass { log_cmd_error("This command only operates on fully selected designs!\n"); RTLIL::Design *crashing_design = clean_design(design, clean); - if (run_yosys(crashing_design, yosys_cmd, yosys_arg)) + if (run_yosys(crashing_design, runner, yosys_cmd, yosys_arg)) log_cmd_error("The provided script file or command and Yosys binary do not crash on this design!\n"); if (!check_logfile(grep)) log_cmd_error("The provided grep string is not found in the log file!\n"); @@ -512,12 +523,12 @@ struct BugpointPass : public Pass { if (clean) { RTLIL::Design *testcase = clean_design(simplified); - crashes = !run_yosys(testcase, yosys_cmd, yosys_arg); + crashes = !run_yosys(testcase, runner, yosys_cmd, yosys_arg); delete testcase; } else { - crashes = !run_yosys(simplified, yosys_cmd, yosys_arg); + crashes = !run_yosys(simplified, runner, yosys_cmd, yosys_arg); } if (crashes && check_logfile(grep)) -- cgit v1.2.3 From 4c39189b137ab3ebcc3db0b5df09c9bf43d97a8c Mon Sep 17 00:00:00 2001 From: Iris Johnson Date: Wed, 24 Mar 2021 16:24:33 -0500 Subject: Clarify bugpoint documentation regarding output Bugpoint's current documentation does specify that the result of a run is stored as the current design, however it's easy to skim over what that means in practice. Add a documentation comment to explain specifically that an after bugpoint `write_xyz` pass is required to save the reduced design. --- passes/cmds/bugpoint.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'passes/cmds') diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 70c002c44..c782d9a38 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -38,6 +38,8 @@ struct BugpointPass : public Pass { log("and the same script, repeating these steps while it can find a smaller design that\n"); log("still causes a crash. Once this command finishes, it replaces the current design\n"); log("with the smallest testcase it was able to produce.\n"); + log("In order to save the reduced testcase you must write this out to a file with\n"); + log("another command after `bugpoint` like `write_rtlil` or `write_verilog`.\n"); log("\n"); log(" -script | -command \"\"\n"); log(" use this script file or command to crash Yosys. required.\n"); -- cgit v1.2.3 From a6081b46ce61a35fee18756de151d72581c8f49b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 5 May 2021 20:32:07 +0200 Subject: connect: Add -assert option, fix non-working sigmap. Should be useful for writing tests. --- passes/cmds/connect.cc | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index 0cc6cbe52..d85ea9ad5 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -60,7 +60,7 @@ struct ConnectPass : public Pass { log("Unconnect all existing drivers for the specified expression.\n"); log("\n"); log("\n"); - log(" connect [-nomap] -port \n"); + log(" connect [-nomap] [-assert] -port \n"); log("\n"); log("Connect the specified cell port to the specified cell port.\n"); log("\n"); @@ -72,6 +72,9 @@ struct ConnectPass : public Pass { log("The connect command operates in one module only. Either only one module must\n"); log("be selected or an active module must be set using the 'cd' command.\n"); log("\n"); + log("The -assert option verifies that the connection already exists, instead of\n"); + log("making it.\n"); + log("\n"); log("This command does not operate on module with processes.\n"); log("\n"); } @@ -88,7 +91,7 @@ struct ConnectPass : public Pass { if (!module->processes.empty()) log_cmd_error("Found processes in selected module.\n"); - bool flag_nounset = false, flag_nomap = false; + bool flag_nounset = false, flag_nomap = false, flag_assert = false; std::string set_lhs, set_rhs, unset_expr; std::string port_cell, port_port, port_expr; @@ -104,6 +107,10 @@ struct ConnectPass : public Pass { flag_nomap = true; continue; } + if (arg == "-assert") { + flag_assert = true; + continue; + } if (arg == "-set" && argidx+2 < args.size()) { set_lhs = args[++argidx]; set_rhs = args[++argidx]; @@ -126,7 +133,7 @@ struct ConnectPass : public Pass { if (!flag_nomap) for (auto &it : module->connections()) { std::vector lhs = it.first.to_sigbit_vector(); - std::vector rhs = it.first.to_sigbit_vector(); + std::vector rhs = it.second.to_sigbit_vector(); for (size_t i = 0; i < lhs.size(); i++) if (rhs[i].wire != nullptr) sigmap.add(lhs[i], rhs[i]); @@ -137,6 +144,9 @@ struct ConnectPass : public Pass { if (!unset_expr.empty() || !port_cell.empty()) log_cmd_error("Can't use -set together with -unset and/or -port.\n"); + if (flag_assert) + log_cmd_error("The -assert option is only supported with -port.\n"); + RTLIL::SigSpec sig_lhs, sig_rhs; if (!RTLIL::SigSpec::parse_sel(sig_lhs, design, module, set_lhs)) log_cmd_error("Failed to parse set lhs expression `%s'.\n", set_lhs.c_str()); @@ -157,6 +167,9 @@ struct ConnectPass : public Pass { if (!port_cell.empty() || flag_nounset) log_cmd_error("Can't use -unset together with -port and/or -nounset.\n"); + if (flag_assert) + log_cmd_error("The -assert option is only supported with -port.\n"); + RTLIL::SigSpec sig; if (!RTLIL::SigSpec::parse_sel(sig, design, module, unset_expr)) log_cmd_error("Failed to parse unset expression `%s'.\n", unset_expr.c_str()); @@ -177,7 +190,14 @@ struct ConnectPass : public Pass { if (!RTLIL::SigSpec::parse_sel(sig, design, module, port_expr)) log_cmd_error("Failed to parse port expression `%s'.\n", port_expr.c_str()); - module->cell(RTLIL::escape_id(port_cell))->setPort(RTLIL::escape_id(port_port), sigmap(sig)); + if (!flag_assert) { + module->cell(RTLIL::escape_id(port_cell))->setPort(RTLIL::escape_id(port_port), sigmap(sig)); + } else { + SigSpec cur = module->cell(RTLIL::escape_id(port_cell))->getPort(RTLIL::escape_id(port_port)); + if (sigmap(sig) != sigmap(cur)) { + log_cmd_error("Expected connection not present: expected %s, found %s.\n", log_signal(sig), log_signal(cur)); + } + } } else log_cmd_error("Expected -set, -unset, or -port.\n"); -- cgit v1.2.3 From c4cc888b2c51a6507b73fdcde1dc61c37384105d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 22 May 2021 19:14:13 +0200 Subject: kernel/rtlil: Extract some helpers for checking memory cell types. There will soon be more (versioned) memory cells, so handle passes that only care if a cell is memory-related by a simple helper call instead of a hardcoded list. --- passes/cmds/delete.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/cmds') diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 684fa37b0..2855f0cdc 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -103,7 +103,7 @@ struct DeletePass : public Pass { for (auto cell : module->cells()) { if (design->selected(module, cell)) delete_cells.insert(cell); - if (cell->type.in(ID($memrd), ID($memwr)) && + if (cell->has_memid() && delete_mems.count(cell->parameters.at(ID::MEMID).decode_string()) != 0) delete_cells.insert(cell); } -- cgit v1.2.3 From 72787f52fc31954e4b7dc3dc34d86705fc4e9dd1 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Tue, 8 Jun 2021 00:39:36 +0200 Subject: Fixing old e-mail addresses and deadnames s/((Claire|Xen|Xenia|Clifford)\s+)+(Wolf|Xen)\s+<(claire|clifford)@(symbioticeda.com|clifford.at|yosyshq.com)>/Claire Xenia Wolf /gi; s/((Nina|Nak|N\.)\s+)+Engelhardt\s+/N. Engelhardt /gi; s/((David)\s+)+Shah\s+<(dave|david)@(symbioticeda.com|yosyshq.com|ds0.me)>/David Shah /gi; s/((Miodrag)\s+)+Milanovic\s+<(miodrag|micko)@(symbioticeda.com|yosyshq.com)>/Miodrag Milanovic /gi; s,https?://www.clifford.at/yosys/,http://yosyshq.net/yosys/,g; --- passes/cmds/add.cc | 2 +- passes/cmds/autoname.cc | 2 +- passes/cmds/blackbox.cc | 2 +- passes/cmds/check.cc | 2 +- passes/cmds/chformal.cc | 2 +- passes/cmds/chtype.cc | 2 +- passes/cmds/connect.cc | 2 +- passes/cmds/connwrappers.cc | 2 +- passes/cmds/copy.cc | 2 +- passes/cmds/cover.cc | 2 +- passes/cmds/delete.cc | 2 +- passes/cmds/design.cc | 2 +- passes/cmds/edgetypes.cc | 2 +- passes/cmds/exec.cc | 2 +- passes/cmds/logcmd.cc | 2 +- passes/cmds/logger.cc | 2 +- passes/cmds/ltp.cc | 2 +- passes/cmds/plugin.cc | 2 +- passes/cmds/portlist.cc | 2 +- passes/cmds/qwp.cc | 2 +- passes/cmds/rename.cc | 2 +- passes/cmds/scatter.cc | 2 +- passes/cmds/scc.cc | 2 +- passes/cmds/scratchpad.cc | 4 ++-- passes/cmds/select.cc | 2 +- passes/cmds/setattr.cc | 2 +- passes/cmds/setundef.cc | 2 +- passes/cmds/show.cc | 2 +- passes/cmds/splice.cc | 2 +- passes/cmds/splitnets.cc | 2 +- passes/cmds/stat.cc | 2 +- passes/cmds/tee.cc | 2 +- passes/cmds/torder.cc | 2 +- passes/cmds/trace.cc | 2 +- passes/cmds/write_file.cc | 2 +- 35 files changed, 36 insertions(+), 36 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index a2f4a9100..c09517254 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/autoname.cc b/passes/cmds/autoname.cc index 28d4012c4..bd4e4a0ca 100644 --- a/passes/cmds/autoname.cc +++ b/passes/cmds/autoname.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/blackbox.cc b/passes/cmds/blackbox.cc index fca91852c..43670efaf 100644 --- a/passes/cmds/blackbox.cc +++ b/passes/cmds/blackbox.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index b502b0788..ee0f0a58f 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/chformal.cc b/passes/cmds/chformal.cc index a1b3fbef7..d813a449c 100644 --- a/passes/cmds/chformal.cc +++ b/passes/cmds/chformal.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/chtype.cc b/passes/cmds/chtype.cc index b894f334c..6f9ca9a45 100644 --- a/passes/cmds/chtype.cc +++ b/passes/cmds/chtype.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index d85ea9ad5..1bd52aab2 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 9235dda2b..dbe23ccf1 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/copy.cc b/passes/cmds/copy.cc index c351065f3..e3fb3a0e6 100644 --- a/passes/cmds/copy.cc +++ b/passes/cmds/copy.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/cover.cc b/passes/cmds/cover.cc index 0867e3b4f..1db3e2ca0 100644 --- a/passes/cmds/cover.cc +++ b/passes/cmds/cover.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 2855f0cdc..48a2179b1 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 2d7ba1fef..169f7cc4a 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/edgetypes.cc b/passes/cmds/edgetypes.cc index 37c420400..5b53f50cc 100644 --- a/passes/cmds/edgetypes.cc +++ b/passes/cmds/edgetypes.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/exec.cc b/passes/cmds/exec.cc index 951fa53fc..f00629a02 100644 --- a/passes/cmds/exec.cc +++ b/passes/cmds/exec.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 - 2020 Claire Wolf + * Copyright (C) 2012 - 2020 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/logcmd.cc b/passes/cmds/logcmd.cc index 12c43ecec..f1702400d 100644 --- a/passes/cmds/logcmd.cc +++ b/passes/cmds/logcmd.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * Copyright (C) 2014 Johann Glaser * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/cmds/logger.cc b/passes/cmds/logger.cc index 6a9ed6036..d06939c2e 100644 --- a/passes/cmds/logger.cc +++ b/passes/cmds/logger.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2020 Miodrag Milanovic + * Copyright (C) 2020 Miodrag Milanovic * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/ltp.cc b/passes/cmds/ltp.cc index 39ec432c2..22bdaab44 100644 --- a/passes/cmds/ltp.cc +++ b/passes/cmds/ltp.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index a94769bcd..3a1ae2850 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/portlist.cc b/passes/cmds/portlist.cc index 97f4bfd99..03048422d 100644 --- a/passes/cmds/portlist.cc +++ b/passes/cmds/portlist.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/qwp.cc b/passes/cmds/qwp.cc index cf0f6d0de..2da612441 100644 --- a/passes/cmds/qwp.cc +++ b/passes/cmds/qwp.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index f8fe715c8..1d08fc514 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/scatter.cc b/passes/cmds/scatter.cc index a70dd3086..017600a46 100644 --- a/passes/cmds/scatter.cc +++ b/passes/cmds/scatter.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 7aa9a484f..81881832c 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/scratchpad.cc b/passes/cmds/scratchpad.cc index 9369f5312..015eb97e7 100644 --- a/passes/cmds/scratchpad.cc +++ b/passes/cmds/scratchpad.cc @@ -1,8 +1,8 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf - * 2019 Nina Engelhardt + * Copyright (C) 2012 Claire Xenia Wolf + * 2019 N. Engelhardt * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index b4f3994a2..bb7b78cfe 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index 3a94209d4..710fa9ab4 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index cf8d76619..a078b0b1c 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index a389c3179..750fe0e10 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index 0f63b91c5..4ad0d2b25 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index fff8a0d3e..927cefca3 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 0d84c73db..422810526 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/tee.cc b/passes/cmds/tee.cc index 60689fc82..7a1f4a36b 100644 --- a/passes/cmds/tee.cc +++ b/passes/cmds/tee.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Claire Xenia Wolf * Copyright (C) 2014 Johann Glaser * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/cmds/torder.cc b/passes/cmds/torder.cc index 30e76081e..9fc7f2e9c 100644 --- a/passes/cmds/torder.cc +++ b/passes/cmds/torder.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/passes/cmds/trace.cc b/passes/cmds/trace.cc index 10742c370..400542776 100644 --- a/passes/cmds/trace.cc +++ b/passes/cmds/trace.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Claire Xenia Wolf * Copyright (C) 2014 Johann Glaser * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/passes/cmds/write_file.cc b/passes/cmds/write_file.cc index 3d898a5ef..ea9b3f556 100644 --- a/passes/cmds/write_file.cc +++ b/passes/cmds/write_file.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Claire Xenia Wolf * Copyright (C) 2014 Johann Glaser * * Permission to use, copy, modify, and/or distribute this software for any -- cgit v1.2.3 From d9f11bb7a631ad309b9328d33b2f41a4987b6222 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 8 Jun 2021 12:06:32 -0400 Subject: autoname: simple perf optimizations --- passes/cmds/autoname.cc | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/autoname.cc b/passes/cmds/autoname.cc index 28d4012c4..addd8d29a 100644 --- a/passes/cmds/autoname.cc +++ b/passes/cmds/autoname.cc @@ -22,25 +22,20 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -int autoname_worker(Module *module) +int autoname_worker(Module *module, const dict& wire_score) { dict> proposed_cell_names; dict> proposed_wire_names; - dict wire_score; int best_score = -1; - for (auto cell : module->selected_cells()) - for (auto &conn : cell->connections()) - for (auto bit : conn.second) - if (bit.wire != nullptr) - wire_score[bit.wire]++; - for (auto cell : module->selected_cells()) { if (cell->name[0] == '$') { for (auto &conn : cell->connections()) { - string suffix = stringf("_%s_%s", log_id(cell->type), log_id(conn.first)); + string suffix; for (auto bit : conn.second) if (bit.wire != nullptr && bit.wire->name[0] != '$') { + if (suffix.empty()) + suffix = stringf("_%s_%s", log_id(cell->type), log_id(conn.first)); IdString new_name(bit.wire->name.str() + suffix); int score = wire_score.at(bit.wire); if (cell->output(conn.first)) score = 0; @@ -54,9 +49,11 @@ int autoname_worker(Module *module) } } else { for (auto &conn : cell->connections()) { - string suffix = stringf("_%s", log_id(conn.first)); + string suffix; for (auto bit : conn.second) if (bit.wire != nullptr && bit.wire->name[0] == '$' && !bit.wire->port_id) { + if (suffix.empty()) + suffix = stringf("_%s", log_id(conn.first)); IdString new_name(cell->name.str() + suffix); int score = wire_score.at(bit.wire); if (cell->output(conn.first)) score = 0; @@ -118,10 +115,17 @@ struct AutonamePass : public Pass { for (auto module : design->selected_modules()) { + dict wire_score; + for (auto cell : module->selected_cells()) + for (auto &conn : cell->connections()) + for (auto bit : conn.second) + if (bit.wire != nullptr) + wire_score[bit.wire]++; + int count = 0, iter = 0; while (1) { iter++; - int n = autoname_worker(module); + int n = autoname_worker(module, wire_score); if (!n) break; count += n; } -- cgit v1.2.3 From 009940f56ca71cc8655a13a514371eb5757b96ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sun, 11 Jul 2021 23:57:53 +0200 Subject: rtlil: Make Process handling more uniform with Cell and Wire. - add a backlink to module from Process - make constructor and destructor protected, expose Module functions to add and remove processes --- passes/cmds/bugpoint.cc | 9 ++++----- passes/cmds/delete.cc | 10 ++++------ 2 files changed, 8 insertions(+), 11 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index c782d9a38..16ac5b6a7 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -275,7 +275,7 @@ struct BugpointPass : public Pass { if (mod->get_blackbox_attribute()) continue; - RTLIL::IdString removed_process; + RTLIL::Process *removed_process = nullptr; for (auto process : mod->processes) { if (process.second->get_bool_attribute(ID::bugpoint_keep)) @@ -284,13 +284,12 @@ struct BugpointPass : public Pass { if (index++ == seed) { log_header(design, "Trying to remove process %s.%s.\n", log_id(mod), log_id(process.first)); - removed_process = process.first; + removed_process = process.second; break; } } - if (!removed_process.empty()) { - delete mod->processes[removed_process]; - mod->processes.erase(removed_process); + if (removed_process) { + mod->remove(removed_process); return design_copy; } } diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 48a2179b1..e341f29d6 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -90,7 +90,7 @@ struct DeletePass : public Pass { pool delete_wires; pool delete_cells; - pool delete_procs; + pool delete_procs; pool delete_mems; for (auto wire : module->selected_wires()) @@ -110,7 +110,7 @@ struct DeletePass : public Pass { for (auto &it : module->processes) if (design->selected(module, it.second)) - delete_procs.insert(it.first); + delete_procs.insert(it.second); for (auto &it : delete_mems) { delete module->memories.at(it); @@ -120,10 +120,8 @@ struct DeletePass : public Pass { for (auto &it : delete_cells) module->remove(it); - for (auto &it : delete_procs) { - delete module->processes.at(it); - module->processes.erase(it); - } + for (auto &it : delete_procs) + module->remove(it); module->remove(delete_wires); -- cgit v1.2.3 From fd7921776387a05edadcc90d1300670d49a73d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 27 May 2021 20:54:29 +0200 Subject: Add v2 memory cells. --- passes/cmds/torder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/cmds') diff --git a/passes/cmds/torder.cc b/passes/cmds/torder.cc index 9fc7f2e9c..1620c0bca 100644 --- a/passes/cmds/torder.cc +++ b/passes/cmds/torder.cc @@ -83,7 +83,7 @@ struct TorderPass : public Pass { if (!noautostop && yosys_celltypes.cell_known(cell->type)) { if (conn.first.in(ID::Q, ID::CTRL_OUT, ID::RD_DATA)) continue; - if (cell->type == ID($memrd) && conn.first == ID::DATA) + if (cell->type.in(ID($memrd), ID($memrd_v2)) && conn.first == ID::DATA) continue; } -- cgit v1.2.3 From c58ac63c97183dde25b7a42c1a8e85ab0dd7fe96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Thu, 12 Aug 2021 17:36:03 +0200 Subject: logger: Add -check-expected subcommand. This allows us to have multiple "expect this warning" calls in a single long script, covering only as many passes as necessary. --- passes/cmds/logger.cc | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'passes/cmds') diff --git a/passes/cmds/logger.cc b/passes/cmds/logger.cc index d06939c2e..ec92f1d01 100644 --- a/passes/cmds/logger.cc +++ b/passes/cmds/logger.cc @@ -64,6 +64,11 @@ struct LoggerPass : public Pass { log(" -expect-no-warnings\n"); log(" gives error in case there is at least one warning that is not expected.\n"); log("\n"); + log(" -check-expected\n"); + log(" verifies that the patterns previously set up by -expect have actually\n"); + log(" been met, then clears the expected log list. If this is not called\n"); + log(" manually, the check will happen at yosys exist time instead.\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design * design) override @@ -176,6 +181,10 @@ struct LoggerPass : public Pass { log_expect_no_warnings = true; continue; } + if (args[argidx] == "-check-expected") { + log_check_expected(); + continue; + } break; } extra_args(args, argidx, design, false); -- cgit v1.2.3 From e7d89e653c9d295d3cc9547b83660658e4d1c95b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 2 Oct 2021 01:23:43 +0200 Subject: Hook up $aldff support in various passes. --- passes/cmds/stat.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/cmds') diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 422810526..14a27ed99 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -120,7 +120,7 @@ struct statdata_t else if (cell_type.in( ID($sr), ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($sdff), ID($sdffe), ID($sdffce), - ID($dlatch), ID($adlatch), ID($dlatchsr))) + ID($aldff), ID($aldffe), ID($dlatch), ID($adlatch), ID($dlatchsr))) cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Q))); } -- cgit v1.2.3 From 107aad2cd2722bc3c35d6c9ab5041477fca0174b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Fri, 12 Nov 2021 11:55:47 +0100 Subject: show: Fix wire bit indexing. Fixes #3078. --- passes/cmds/show.cc | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'passes/cmds') diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 750fe0e10..8f9824f9b 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -239,6 +239,19 @@ struct ShowWorker int idx = single_idx_count++; for (int rep, i = int(sig.chunks().size())-1; i >= 0; i -= rep) { const RTLIL::SigChunk &c = sig.chunks().at(i); + int cl, cr; + if (c.wire) { + if (c.wire->upto) { + cr = c.wire->start_offset + (c.wire->width - c.offset - 1); + cl = cr - (c.width - 1); + } else { + cr = c.wire->start_offset + c.offset; + cl = cr + c.width - 1; + } + } else { + cl = c.offset + c.width - 1; + cr = c.offset; + } if (!driver && c.wire == nullptr) { RTLIL::State s1 = c.data.front(); for (auto s2 : c.data) @@ -254,7 +267,7 @@ struct ShowWorker std::string repinfo = rep > 1 ? stringf("%dx ", rep) : ""; if (driver) { log_assert(!net.empty()); - label_string += stringf(" %d:%d - %s%d:%d |", i, pos, pos-c.width+1, repinfo.c_str(), c.offset+c.width-1, c.offset); + label_string += stringf(" %d:%d - %s%d:%d |", i, pos, pos-c.width+1, repinfo.c_str(), cl, cr); net_conn_map[net].in.insert(stringf("x%d:s%d", idx, i)); net_conn_map[net].bits = rep*c.width; net_conn_map[net].color = nextColor(c, net_conn_map[net].color); @@ -268,7 +281,7 @@ struct ShowWorker c.data.front() == State::Sz ? 'Z' : '?', pos, pos-rep*c.width+1); } else { - label_string += stringf(" %s%d:%d - %d:%d |", i, repinfo.c_str(), c.offset+c.width-1, c.offset, pos, pos-rep*c.width+1); + label_string += stringf(" %s%d:%d - %d:%d |", i, repinfo.c_str(), cl, cr, pos, pos-rep*c.width+1); net_conn_map[net].out.insert(stringf("x%d:s%d", idx, i)); net_conn_map[net].bits = rep*c.width; net_conn_map[net].color = nextColor(c, net_conn_map[net].color); @@ -653,7 +666,7 @@ struct ShowPass : public Pass { log(" (including inout ports) are on the right side.\n"); log("\n"); log(" -pause\n"); - log(" wait for the use to press enter to before returning\n"); + log(" wait for the user to press enter to before returning\n"); log("\n"); log(" -enum\n"); log(" enumerate objects with internal ($-prefixed) names\n"); -- cgit v1.2.3 From 77327b2544a30b15e8efc79e1f62661ff25d306c Mon Sep 17 00:00:00 2001 From: Lofty Date: Wed, 24 Nov 2021 21:21:08 +0000 Subject: sta: very crude static timing analysis pass Co-authored-by: Eddie Hung --- passes/cmds/Makefile.inc | 1 + passes/cmds/sta.cc | 312 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 313 insertions(+) create mode 100644 passes/cmds/sta.cc (limited to 'passes/cmds') diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 53bfd40c6..01e052fdf 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -40,3 +40,4 @@ endif OBJS += passes/cmds/scratchpad.o OBJS += passes/cmds/logger.o OBJS += passes/cmds/printattrs.o +OBJS += passes/cmds/sta.o \ No newline at end of file diff --git a/passes/cmds/sta.cc b/passes/cmds/sta.cc new file mode 100644 index 000000000..13e1ee13c --- /dev/null +++ b/passes/cmds/sta.cc @@ -0,0 +1,312 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * (C) 2019 Eddie Hung + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/yosys.h" +#include "kernel/sigtools.h" +#include "kernel/timinginfo.h" +#include + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct StaWorker +{ + Design *design; + Module *module; + SigMap sigmap; + + struct t_data { + Cell* driver; + IdString dst_port, src_port; + vector> fanouts; + SigBit backtrack; + t_data() : driver(nullptr) {} + }; + dict data; + std::deque queue; + struct t_endpoint { + Cell *sink; + IdString port; + int required; + t_endpoint() : sink(nullptr), required(0) {} + }; + dict endpoints; + + int maxarrival; + SigBit maxbit; + + pool driven; + + StaWorker(RTLIL::Module *module) : design(module->design), module(module), sigmap(module), maxarrival(0) + { + TimingInfo timing; + + for (auto cell : module->cells()) + { + Module *inst_module = design->module(cell->type); + if (!inst_module) { + log_warning("Cell type '%s' not recognised! Ignoring.\n", log_id(cell->type)); + continue; + } + + if (!inst_module->get_blackbox_attribute()) { + log_warning("Cell type '%s' is not a black- nor white-box! Ignoring.\n", log_id(cell->type)); + continue; + } + + IdString derived_type = inst_module->derive(design, cell->parameters); + inst_module = design->module(derived_type); + log_assert(inst_module); + + if (!timing.count(derived_type)) { + auto &t = timing.setup_module(inst_module); + if (t.has_inputs && t.comb.empty() && t.arrival.empty() && t.required.empty()) + log_warning("Module '%s' has no timing arcs!\n", log_id(cell->type)); + } + + auto &t = timing.at(derived_type); + if (t.comb.empty() && t.arrival.empty() && t.required.empty()) + continue; + + pool> src_bits, dst_bits; + + for (auto &conn : cell->connections()) { + auto rhs = sigmap(conn.second); + for (auto i = 0; i < GetSize(rhs); i++) { + const auto &bit = rhs[i]; + if (!bit.wire) + continue; + TimingInfo::NameBit namebit(conn.first,i); + if (cell->input(conn.first)) { + src_bits.insert(std::make_pair(bit,namebit)); + + auto it = t.required.find(namebit); + if (it == t.required.end()) + continue; + auto r = endpoints.insert(bit); + if (r.second || r.first->second.required < it->second.first) { + r.first->second.sink = cell; + r.first->second.port = conn.first; + r.first->second.required = it->second.first; + } + } + if (cell->output(conn.first)) { + dst_bits.insert(std::make_pair(bit,namebit)); + auto &d = data[bit]; + d.driver = cell; + d.dst_port = conn.first; + driven.insert(bit); + + auto it = t.arrival.find(namebit); + if (it == t.arrival.end()) + continue; + const auto &s = it->second.second; + if (cell->hasPort(s.name)) { + auto s_bit = sigmap(cell->getPort(s.name)[s.offset]); + if (s_bit.wire) + data[s_bit].fanouts.emplace_back(bit,it->second.first,s.name); + } + } + } + } + + for (const auto &s : src_bits) + for (const auto &d : dst_bits) { + auto it = t.comb.find(TimingInfo::BitBit(s.second,d.second)); + if (it == t.comb.end()) + continue; + data[s.first].fanouts.emplace_back(d.first,it->second,s.second.name); + } + } + + for (auto port_name : module->ports) { + auto wire = module->wire(port_name); + if (wire->port_input) { + for (const auto &b : sigmap(wire)) { + queue.emplace_back(b); + driven.insert(b); + } + // All primary inputs to arrive at time zero + wire->set_intvec_attribute(ID::sta_arrival, std::vector(GetSize(wire), 0)); + } + if (wire->port_output) + for (const auto &b : sigmap(wire)) + if (b.wire) + endpoints.insert(b); + } + } + + void run() + { + while (!queue.empty()) { + auto b = queue.front(); + queue.pop_front(); + auto it = data.find(b); + if (it == data.end()) + continue; + const auto& src_arrivals = b.wire->get_intvec_attribute(ID::sta_arrival); + log_assert(GetSize(src_arrivals) == GetSize(b.wire)); + auto src_arrival = src_arrivals[b.offset]; + for (const auto &d : it->second.fanouts) { + const auto &dst_bit = std::get<0>(d); + auto dst_arrivals = dst_bit.wire->get_intvec_attribute(ID::sta_arrival); + if (dst_arrivals.empty()) + dst_arrivals = std::vector(GetSize(dst_bit.wire), -1); + else + log_assert(GetSize(dst_arrivals) == GetSize(dst_bit.wire)); + auto &dst_arrival = dst_arrivals[dst_bit.offset]; + auto new_arrival = src_arrival + std::get<1>(d); + if (dst_arrival < new_arrival) { + auto dst_wire = dst_bit.wire; + dst_arrival = std::max(dst_arrival, new_arrival); + dst_wire->set_intvec_attribute(ID::sta_arrival, dst_arrivals); + queue.emplace_back(dst_bit); + + data[dst_bit].backtrack = b; + data[dst_bit].src_port = std::get<2>(d); + + auto it = endpoints.find(dst_bit); + if (it != endpoints.end()) + new_arrival += it->second.required; + if (new_arrival > maxarrival && driven.count(b)) { + maxarrival = new_arrival; + maxbit = dst_bit; + } + } + } + } + + auto b = maxbit; + if (b == SigBit()) { + log("No timing paths found.\n"); + return; + } + + log("Latest arrival time in '%s' is %d:\n", log_id(module), maxarrival); + auto it = endpoints.find(maxbit); + if (it != endpoints.end() && it->second.sink) + log(" %6d %s (%s.%s)\n", maxarrival, log_id(it->second.sink), log_id(it->second.sink->type), log_id(it->second.port)); + else { + log(" %6d (%s)\n", maxarrival, b.wire->port_output ? "" : ""); + if (!b.wire->port_output) + log_warning("Critical-path does not terminate in a recognised endpoint.\n"); + } + auto jt = data.find(b); + while (jt != data.end()) { + int arrival = b.wire->get_intvec_attribute(ID::sta_arrival)[b.offset]; + if (jt->second.driver) { + log(" %s\n", log_signal(b)); + log(" %6d %s (%s.%s->%s)\n", arrival, log_id(jt->second.driver), log_id(jt->second.driver->type), log_id(jt->second.src_port), log_id(jt->second.dst_port)); + } + else if (b.wire->port_input) + log(" %6d %s (%s)\n", arrival, log_signal(b), ""); + else + log_abort(); + b = jt->second.backtrack; + jt = data.find(b); + } + + std::map arrival_histogram; + for (const auto &i : endpoints) { + const auto &b = i.first; + if (!driven.count(b)) + continue; + + if (!b.wire->attributes.count(ID::sta_arrival)) { + log_warning("Endpoint %s.%s has no (* sta_arrival *) value.\n", log_id(module), log_signal(b)); + continue; + } + + auto arrival = b.wire->get_intvec_attribute(ID::sta_arrival)[b.offset]; + if (arrival < 0) { + log_warning("Endpoint %s.%s has no (* sta_arrival *) value.\n", log_id(module), log_signal(b)); + continue; + } + arrival += i.second.required; + arrival_histogram[arrival]++; + } + // Adapted from https://github.com/YosysHQ/nextpnr/blob/affb12cc27ebf409eade062c4c59bb98569d8147/common/timing.cc#L946-L969 + if (arrival_histogram.size() > 0) { + unsigned num_bins = 20; + unsigned bar_width = 60; + auto min_arrival = arrival_histogram.begin()->first; + auto max_arrival = arrival_histogram.rbegin()->first; + auto bin_size = std::max(1, ceil((max_arrival - min_arrival + 1) / float(num_bins))); + std::vector bins(num_bins); + unsigned max_freq = 0; + for (const auto &i : arrival_histogram) { + auto &bin = bins[(i.first - min_arrival) / bin_size]; + bin += i.second; + max_freq = std::max(max_freq, bin); + } + bar_width = std::min(bar_width, max_freq); + + log("\n"); + log("Arrival histogram:\n"); + log(" legend: * represents %d endpoint(s)\n", max_freq / bar_width); + log(" + represents [1,%d) endpoint(s)\n", max_freq / bar_width); + for (int i = num_bins-1; i >= 0; --i) + log("(%6d, %6d] |%s%c\n", min_arrival + bin_size * (i + 1), min_arrival + bin_size * i, + std::string(bins[i] * bar_width / max_freq, '*').c_str(), + (bins[i] * bar_width) % max_freq > 0 ? '+' : ' '); + } + } +}; + +struct StaPass : public Pass { + StaPass() : Pass("sta", "perform static timing analysis") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" sta [options] [selection]\n"); + log("\n"); + log("This command performs static timing analysis on the design. (Only considers\n"); + log("paths within a single module, so the design must be flattened.)\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + log_header(design, "Executing STA pass (static timing analysis).\n"); + + /* + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-TODO") { + continue; + } + break; + } + */ + + extra_args(args, 1, design); + + for (Module *module : design->selected_modules()) + { + if (module->has_processes_warn()) + continue; + + StaWorker worker(module); + worker.run(); + } + } +} StaPass; + +PRIVATE_NAMESPACE_END -- cgit v1.2.3 From 0aad88a2fb23e5481538122e1bd4c0fac9ba5e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 11 Dec 2021 16:07:29 +0100 Subject: Add clean_zerowidth pass, use it for Verilog output. This should remove instances of zero-width sigspecs in the netlist, avoiding problems in the Verilog backend with emitting them. See #3103. --- passes/cmds/Makefile.inc | 3 +- passes/cmds/clean_zerowidth.cc | 210 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 passes/cmds/clean_zerowidth.cc (limited to 'passes/cmds') diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 01e052fdf..917856767 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -40,4 +40,5 @@ endif OBJS += passes/cmds/scratchpad.o OBJS += passes/cmds/logger.o OBJS += passes/cmds/printattrs.o -OBJS += passes/cmds/sta.o \ No newline at end of file +OBJS += passes/cmds/sta.o +OBJS += passes/cmds/clean_zerowidth.o diff --git a/passes/cmds/clean_zerowidth.cc b/passes/cmds/clean_zerowidth.cc new file mode 100644 index 000000000..4e7c68093 --- /dev/null +++ b/passes/cmds/clean_zerowidth.cc @@ -0,0 +1,210 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2021 Marcelina Kościelnicka + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/yosys.h" +#include "kernel/celltypes.h" +#include "kernel/mem.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct CleanZeroWidthPass : public Pass { + CleanZeroWidthPass() : Pass("clean_zerowidth", "clean zero-width connections from the design") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" clean_zerowidth [selection]\n"); + log("\n"); + log("Fixes the selected cells and processes to contain no zero-width connections.\n"); + log("Depending on the cell type, this may be implemented by removing the connection,\n"); + log("widening it to 1-bit, or removing the cell altogether.\n"); + log("\n"); + } + + void clean_case(RTLIL::CaseRule *cs) + { + std::vector new_actions; + for (auto &action : cs->actions) + if (GetSize(action.first) != 0) + new_actions.push_back(action); + std::swap(new_actions, cs->actions); + for (auto sw : cs->switches) + for (auto scs : sw->cases) + clean_case(scs); + } + + void execute(std::vector args, RTLIL::Design *design) override + { + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + break; + } + extra_args(args, argidx, design); + + CellTypes ct; + ct.setup(); + + for (auto module : design->selected_modules()) + { + for (auto cell : module->selected_cells()) + { + if (!ct.cell_known(cell->type)) { + // User-defined cell: just prune zero-width connections. + for (auto it: cell->connections()) { + if (GetSize(it.second) == 0) { + cell->unsetPort(it.first); + } + } + } else if (RTLIL::builtin_ff_cell_types().count(cell->type)) { + // Coarse FF cells: remove if WIDTH == 0 (no outputs). + // This will also trigger on fine cells, so use the Q port + // width instead of actual WIDTH parameter. + if (GetSize(cell->getPort(ID::Q)) == 0) { + module->remove(cell); + } + } else if (cell->type == ID($pmux)) { + // Remove altogether if WIDTH is 0, replace with + // a connection if S_WIDTH is 0. + if (cell->getParam(ID::WIDTH).as_int() == 0) { + module->remove(cell); + } + if (cell->getParam(ID::S_WIDTH).as_int() == 0) { + module->connect(cell->getPort(ID::Y), cell->getPort(ID::A)); + module->remove(cell); + } + } else if (cell->type == ID($concat)) { + // If a concat has a zero-width input: replace with direct + // connection to the other input. + if (cell->getParam(ID::A_WIDTH).as_int() == 0) { + module->connect(cell->getPort(ID::Y), cell->getPort(ID::B)); + module->remove(cell); + } else if (cell->getParam(ID::B_WIDTH).as_int() == 0) { + module->connect(cell->getPort(ID::Y), cell->getPort(ID::A)); + module->remove(cell); + } + } else if (cell->type == ID($fsm)) { + // TODO: not supported + } else if (cell->is_mem_cell()) { + // Skip — will be handled below. + } else if (cell->type == ID($lut)) { + // Zero-width LUT is just a const driver. + if (cell->getParam(ID::WIDTH).as_int() == 0) { + module->connect(cell->getPort(ID::Y), cell->getParam(ID::LUT)[0]); + module->remove(cell); + } + } else if (cell->type == ID($sop)) { + // Zero-width SOP is just a const driver. + if (cell->getParam(ID::WIDTH).as_int() == 0) { + // The value is 1 iff DEPTH is non-0. + bool val = cell->getParam(ID::DEPTH).as_int() != 0; + module->connect(cell->getPort(ID::Y), val); + module->remove(cell); + } + } else if (cell->hasParam(ID::WIDTH)) { + // For cells with WIDTH parameter: remove if zero. + if (cell->getParam(ID::WIDTH).as_int() == 0) { + module->remove(cell); + } + } else if (cell->hasParam(ID::Y_WIDTH)) { + // For most operators: remove if Y width is 0, expand + // A and B to 1-bit if their width is 0. + if (cell->getParam(ID::Y_WIDTH).as_int() == 0) { + module->remove(cell); + } else if (cell->type == ID($macc)) { + // TODO: fixing zero-width A and B not supported. + } else { + if (cell->getParam(ID::A_WIDTH).as_int() == 0) { + cell->setPort(ID::A, State::S0); + cell->setParam(ID::A_WIDTH, 1); + } + if (cell->hasParam(ID::B_WIDTH) && cell->getParam(ID::B_WIDTH).as_int() == 0) { + cell->setPort(ID::B, State::S0); + cell->setParam(ID::B_WIDTH, 1); + } + } + } + } + + // NOTE: Zero-width switch signals are left alone for processes, as there + // is no simple way of cleaning them up. + for (auto &it: module->processes) { + if (!design->selected(module, it.second)) + continue; + clean_case(&it.second->root_case); + for (auto sync : it.second->syncs) { + std::vector swizzle; + std::vector new_memwr_actions; + for (int i = 0; i < GetSize(sync->mem_write_actions); i++) { + auto &memwr = sync->mem_write_actions[i]; + if (GetSize(memwr.data) == 0) + continue; + if (GetSize(memwr.address) == 0) + memwr.address = State::S0; + Const priority_mask; + for (auto x : swizzle) { + priority_mask.bits.push_back(memwr.priority_mask.bits[x]); + } + memwr.priority_mask = priority_mask; + swizzle.push_back(i); + new_memwr_actions.push_back(memwr); + } + std::swap(new_memwr_actions, sync->mem_write_actions); + std::vector new_actions; + for (auto &action : sync->actions) + if (GetSize(action.first) != 0) + new_actions.push_back(action); + std::swap(new_actions, sync->actions); + } + } + + for (auto &mem : Mem::get_selected_memories(module)) { + if (mem.width == 0) { + mem.remove(); + continue; + } + for (auto &init : mem.inits) { + if (GetSize(init.addr) == 0) { + init.addr = State::S0; + } + } + for (auto &port : mem.rd_ports) { + if (GetSize(port.addr) == 0) { + port.addr = State::S0; + } + } + for (auto &port : mem.wr_ports) { + if (GetSize(port.addr) == 0) { + port.addr = State::S0; + } + } + mem.emit(); + } + + std::vector new_conns; + for (auto &conn : module->connections()) + if (GetSize(conn.first) != 0) + new_conns.push_back(conn); + module->new_connections(new_conns); + } + } +} CleanZeroWidthPass; + +PRIVATE_NAMESPACE_END -- cgit v1.2.3 From 4f1d62d9b25208f23a08b21247d016c44df01c26 Mon Sep 17 00:00:00 2001 From: Catherine Date: Wed, 15 Dec 2021 08:15:54 +0000 Subject: bugpoint: avoid infinite loop between -connections and -wires. Fixes #3113. --- passes/cmds/bugpoint.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/cmds') diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 16ac5b6a7..7b621504d 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -377,7 +377,7 @@ struct BugpointPass : public Pass { if (wire->get_bool_attribute(ID::bugpoint_keep)) continue; - if (wire->name.begins_with("$delete_wire")) + if (wire->name.begins_with("$delete_wire") || wire->name.begins_with("$auto$bugpoint")) continue; if (index++ == seed) -- cgit v1.2.3 From 93508d58dafbbffcedffa70b21a197b6fca8bb30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Mon, 24 Jan 2022 16:02:29 +0100 Subject: Add $bmux and $demux cells. --- passes/cmds/clean_zerowidth.cc | 2 +- passes/cmds/stat.cc | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'passes/cmds') diff --git a/passes/cmds/clean_zerowidth.cc b/passes/cmds/clean_zerowidth.cc index 4e7c68093..bac6b1521 100644 --- a/passes/cmds/clean_zerowidth.cc +++ b/passes/cmds/clean_zerowidth.cc @@ -80,7 +80,7 @@ struct CleanZeroWidthPass : public Pass { if (GetSize(cell->getPort(ID::Q)) == 0) { module->remove(cell); } - } else if (cell->type == ID($pmux)) { + } else if (cell->type.in(ID($pmux), ID($bmux), ID($demux))) { // Remove altogether if WIDTH is 0, replace with // a connection if S_WIDTH is 0. if (cell->getParam(ID::WIDTH).as_int() == 0) { diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 14a27ed99..fffdda48e 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -117,6 +117,10 @@ struct statdata_t } else if (cell_type.in(ID($mux), ID($pmux))) cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Y))); + else if (cell_type == ID($bmux)) + cell_type = stringf("%s_%d_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Y)), GetSize(cell->getPort(ID::S))); + else if (cell_type == ID($demux)) + cell_type = stringf("%s_%d_%d", cell_type.c_str(), GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::S))); else if (cell_type.in( ID($sr), ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($sdff), ID($sdffe), ID($sdffce), -- cgit v1.2.3