diff options
Diffstat (limited to 'passes')
-rw-r--r-- | passes/techmap/Makefile.inc | 1 | ||||
-rw-r--r-- | passes/techmap/abc9.cc | 69 | ||||
-rw-r--r-- | passes/techmap/pmux2shiftx.cc | 82 | ||||
-rw-r--r-- | passes/techmap/pmuxtree.cc | 4 |
4 files changed, 138 insertions, 18 deletions
diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index c45571b01..ca5818248 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -38,6 +38,7 @@ OBJS += passes/techmap/attrmap.o OBJS += passes/techmap/zinit.o OBJS += passes/techmap/dff2dffs.o OBJS += passes/techmap/flowmap.o +OBJS += passes/techmap/pmux2shiftx.o endif GENFILES += passes/techmap/techmap.inc diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index edc07092b..caaff9256 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -272,7 +272,7 @@ failed: void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, std::string liberty_file, std::string constr_file, bool cleanup, vector<int> lut_costs, bool dff_mode, std::string clk_str, bool keepff, std::string delay_target, std::string sop_inputs, std::string sop_products, std::string lutin_shared, bool fast_mode, - const std::vector<RTLIL::Cell*> &cells, bool show_tempdir, bool sop_mode) + const std::vector<RTLIL::Cell*> &cells, bool show_tempdir, bool sop_mode, std::string box_file, std::string lut_file) { module = current_module; map_autoidx = autoidx++; @@ -329,8 +329,17 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri if (!constr_file.empty()) abc_script += stringf("read_constr -v %s; ", constr_file.c_str()); } else - if (!lut_costs.empty()) + if (!lut_costs.empty()) { abc_script += stringf("read_lut %s/lutdefs.txt; ", tempdir_name.c_str()); + if (!box_file.empty()) + abc_script += stringf("read_box -v %s; ", box_file.c_str()); + } + else + if (!lut_file.empty()) { + abc_script += stringf("read_lut %s; ", lut_file.c_str()); + if (!box_file.empty()) + abc_script += stringf("read_box -v %s; ", box_file.c_str()); + } else abc_script += stringf("read_library %s/stdcells.genlib; ", tempdir_name.c_str()); @@ -345,11 +354,11 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri abc_script += script_file[i]; } else abc_script += stringf("source %s", script_file.c_str()); - } else if (!lut_costs.empty()) { - bool all_luts_cost_same = true; - for (int this_cost : lut_costs) - if (this_cost != lut_costs.front()) - all_luts_cost_same = false; + } else if (!lut_costs.empty() || !lut_file.empty()) { + //bool all_luts_cost_same = true; + //for (int this_cost : lut_costs) + // if (this_cost != lut_costs.front()) + // all_luts_cost_same = false; abc_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; //if (all_luts_cost_same && !fast_mode) // abc_script += "; lutpack {S}"; @@ -403,6 +412,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri RTLIL::Selection& sel = design->selection_stack.back(); sel.select(module); + // Adopt same behaviour as abc + // TODO: How to specify don't-care to abc9? + Pass::call(design, "setundef -zero"); + Pass::call(design, "aigmap"); handle_loops(design); @@ -573,7 +586,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri RTLIL::Cell *cell; RTLIL::SigBit a_bit = c->getPort("\\A").as_bit(); RTLIL::SigBit y_bit = c->getPort("\\Y").as_bit(); - if (!lut_costs.empty()) { + if (!lut_costs.empty() || !lut_file.empty()) { // ABC can return NOT gates that drive POs if (a_bit.wire->port_input) { // If it's a NOT gate that comes from a primary input directly @@ -1001,7 +1014,7 @@ struct Abc9Pass : public Pass { log(" file format).\n"); log("\n"); log(" -constr <file>\n"); - log(" pass this file with timing constraints to ABC. use with -liberty.\n"); + log(" pass this file with timing constraints to ABC. Use with -liberty.\n"); log("\n"); log(" a constr file contains two lines:\n"); log(" set_driving_cell <cell_name>\n"); @@ -1038,6 +1051,9 @@ struct Abc9Pass : public Pass { log(" the area cost doubles with each additional input bit. the delay cost\n"); log(" is still constant for all lut widths.\n"); log("\n"); + log(" -lut <file>\n"); + log(" pass this file with lut library to ABC.\n"); + log("\n"); log(" -luts <cost1>,<cost2>,<cost3>,<sizeN>:<cost4-N>,..\n"); log(" generate netlist using luts. Use the specified costs for luts with 1,\n"); log(" 2, 3, .. inputs.\n"); @@ -1091,6 +1107,9 @@ struct Abc9Pass : public Pass { log(" this attribute is a unique integer for each ABC process started. This\n"); log(" is useful for debugging the partitioning of clock domains.\n"); log("\n"); + log(" -box <file>\n"); + log(" pass this file with box library to ABC. Use with -lut.\n"); + log("\n"); log("When neither -liberty nor -lut is used, the Yosys standard cell library is\n"); log("loaded into ABC before the ABC script is executed.\n"); log("\n"); @@ -1120,7 +1139,7 @@ struct Abc9Pass : public Pass { #else std::string exe_file = proc_self_dirname() + "yosys-abc"; #endif - std::string script_file, liberty_file, constr_file, clk_str; + std::string script_file, liberty_file, constr_file, clk_str, box_file, lut_file; std::string delay_target, sop_inputs, sop_products, lutin_shared = "-S 1"; bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true; bool show_tempdir = false, sop_mode = false; @@ -1166,8 +1185,8 @@ struct Abc9Pass : public Pass { continue; } if (arg == "-constr" && argidx+1 < args.size()) { - rewrite_filename(constr_file); constr_file = args[++argidx]; + rewrite_filename(constr_file); if (!constr_file.empty() && !is_absolute_path(constr_file)) constr_file = std::string(pwd) + "/" + constr_file; continue; @@ -1196,8 +1215,17 @@ struct Abc9Pass : public Pass { lut_mode = atoi(arg.substr(0, pos).c_str()); lut_mode2 = atoi(arg.substr(pos+1).c_str()); } else { - lut_mode = atoi(arg.c_str()); - lut_mode2 = lut_mode; + pos = arg.find_first_of('.'); + if (pos != string::npos) { + lut_file = arg; + rewrite_filename(lut_file); + if (!lut_file.empty() && !is_absolute_path(lut_file)) + lut_file = std::string(pwd) + "/" + lut_file; + } + else { + lut_mode = atoi(arg.c_str()); + lut_mode2 = lut_mode; + } } lut_costs.clear(); for (int i = 0; i < lut_mode; i++) @@ -1354,11 +1382,18 @@ struct Abc9Pass : public Pass { markgroups = true; continue; } + if (arg == "-box" && argidx+1 < args.size()) { + box_file = args[++argidx]; + rewrite_filename(box_file); + if (!box_file.empty() && !is_absolute_path(box_file)) + box_file = std::string(pwd) + "/" + box_file; + continue; + } break; } extra_args(args, argidx, design); - if (!lut_costs.empty() && !liberty_file.empty()) + if ((!lut_costs.empty() || !lut_file.empty()) && !liberty_file.empty()) log_cmd_error("Got -lut and -liberty! This two options are exclusive.\n"); if (!constr_file.empty() && liberty_file.empty()) log_cmd_error("Got -constr but no -liberty!\n"); @@ -1392,7 +1427,8 @@ struct Abc9Pass : public Pass { if (!dff_mode || !clk_str.empty()) { abc9_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff, - delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode); + delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode, + box_file, lut_file); continue; } @@ -1537,7 +1573,8 @@ struct Abc9Pass : public Pass { en_polarity = std::get<2>(it.first); en_sig = assign_map(std::get<3>(it.first)); abc9_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$", - keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode); + keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode, + box_file, lut_file); assign_map.set(mod); } } diff --git a/passes/techmap/pmux2shiftx.cc b/passes/techmap/pmux2shiftx.cc new file mode 100644 index 000000000..f8cdf5783 --- /dev/null +++ b/passes/techmap/pmux2shiftx.cc @@ -0,0 +1,82 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> + * + * 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" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct Pmux2ShiftxPass : public Pass { + Pmux2ShiftxPass() : Pass("pmux2shiftx", "transform $pmux cells to $shiftx cells") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" pmux2shiftx [selection]\n"); + log("\n"); + log("This pass transforms $pmux cells to $shiftx cells.\n"); + log("\n"); + } + void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing PMUX2SHIFTX pass.\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + break; + } + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) + for (auto cell : module->selected_cells()) + { + if (cell->type != "$pmux") + continue; + + // Create a new encoder, out of a $pmux, that takes + // the existing pmux's 'S' input and transforms it + // back into a binary value + RTLIL::SigSpec shiftx_a; + RTLIL::SigSpec pmux_s; + + int s_width = cell->getParam("\\S_WIDTH").as_int(); + if (!cell->getPort("\\A").is_fully_undef()) { + ++s_width; + shiftx_a.append(cell->getPort("\\A")); + pmux_s.append(module->Not(NEW_ID, module->ReduceOr(NEW_ID, cell->getPort("\\S")))); + } + const int clog2width = ceil(log2(s_width)); + + RTLIL::SigSpec pmux_b; + pmux_b.append(RTLIL::Const(0, clog2width)); + for (int i = s_width-1; i > 0; i--) + pmux_b.append(RTLIL::Const(i, clog2width)); + shiftx_a.append(cell->getPort("\\B")); + pmux_s.append(cell->getPort("\\S")); + + RTLIL::SigSpec pmux_y = module->addWire(NEW_ID, clog2width); + module->addPmux(NEW_ID, RTLIL::Const(RTLIL::Sx, clog2width), pmux_b, pmux_s, pmux_y); + module->addShiftx(NEW_ID, shiftx_a, pmux_y, cell->getPort("\\Y")); + module->remove(cell); + } + } +} Pmux2ShiftxPass; + +PRIVATE_NAMESPACE_END diff --git a/passes/techmap/pmuxtree.cc b/passes/techmap/pmuxtree.cc index b7a22dc3b..6a923f481 100644 --- a/passes/techmap/pmuxtree.cc +++ b/passes/techmap/pmuxtree.cc @@ -71,9 +71,9 @@ struct PmuxtreePass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" pmuxtree [options] [selection]\n"); + log(" pmuxtree [selection]\n"); log("\n"); - log("This pass transforms $pmux cells to a trees of $mux cells.\n"); + log("This pass transforms $pmux cells to trees of $mux cells.\n"); log("\n"); } void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE |