diff options
Diffstat (limited to 'passes/cmds')
-rw-r--r-- | passes/cmds/check.cc | 2 | ||||
-rw-r--r-- | passes/cmds/connwrappers.cc | 2 | ||||
-rw-r--r-- | passes/cmds/cover.cc | 2 | ||||
-rw-r--r-- | passes/cmds/plugin.cc | 8 | ||||
-rw-r--r-- | passes/cmds/qwp.cc | 32 | ||||
-rw-r--r-- | passes/cmds/scc.cc | 8 | ||||
-rw-r--r-- | passes/cmds/select.cc | 42 | ||||
-rw-r--r-- | passes/cmds/setattr.cc | 6 | ||||
-rw-r--r-- | passes/cmds/setundef.cc | 94 | ||||
-rw-r--r-- | passes/cmds/show.cc | 18 | ||||
-rw-r--r-- | passes/cmds/splice.cc | 2 | ||||
-rw-r--r-- | passes/cmds/splitnets.cc | 2 | ||||
-rw-r--r-- | passes/cmds/stat.cc | 2 | ||||
-rw-r--r-- | passes/cmds/tee.cc | 10 | ||||
-rw-r--r-- | passes/cmds/torder.cc | 2 |
15 files changed, 196 insertions, 36 deletions
diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index 2ad84838..b3622cb1 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -68,7 +68,7 @@ struct CheckPass : public Pass { } extra_args(args, argidx, design); - log_header("Executing CHECK pass (checking for obvious problems).\n"); + log_header(design, "Executing CHECK pass (checking for obvious problems).\n"); for (auto module : design->selected_whole_modules_warn()) { diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 7828dce1..c9ab226d 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -198,7 +198,7 @@ struct ConnwrappersPass : public Pass { } extra_args(args, argidx, design); - log_header("Executing CONNWRAPPERS pass (connect extended ports of wrapper cells).\n"); + log_header(design, "Executing CONNWRAPPERS pass (connect extended ports of wrapper cells).\n"); for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) diff --git a/passes/cmds/cover.cc b/passes/cmds/cover.cc index 5644066a..1475475c 100644 --- a/passes/cmds/cover.cc +++ b/passes/cmds/cover.cc @@ -124,7 +124,7 @@ struct CoverPass : public Pass { extra_args(args, argidx, design); if (do_log) { - log_header("Printing code coverage counters.\n"); + log_header(design, "Printing code coverage counters.\n"); log("\n"); } diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index e2d80d9b..828c671d 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -31,19 +31,23 @@ std::map<std::string, std::string> loaded_plugin_aliases; #ifdef YOSYS_ENABLE_PLUGINS void load_plugin(std::string filename, std::vector<std::string> aliases) { + std::string orig_filename = filename; + if (filename.find('/') == std::string::npos) filename = "./" + filename; if (!loaded_plugins.count(filename)) { void *hdl = dlopen(filename.c_str(), RTLD_LAZY|RTLD_LOCAL); + if (hdl == NULL && orig_filename.find('/') == std::string::npos) + hdl = dlopen((proc_share_dirname() + "plugins/" + orig_filename + ".so").c_str(), RTLD_LAZY|RTLD_LOCAL); if (hdl == NULL) log_cmd_error("Can't load module `%s': %s\n", filename.c_str(), dlerror()); - loaded_plugins[filename] = hdl; + loaded_plugins[orig_filename] = hdl; Pass::init_register(); } for (auto &alias : aliases) - loaded_plugin_aliases[alias] = filename; + loaded_plugin_aliases[alias] = orig_filename; } #else void load_plugin(std::string, std::vector<std::string>) diff --git a/passes/cmds/qwp.cc b/passes/cmds/qwp.cc index 8ec815a7..1b800b6d 100644 --- a/passes/cmds/qwp.cc +++ b/passes/cmds/qwp.cc @@ -40,6 +40,7 @@ struct QwpConfig { bool ltr; bool alpha; + bool verbose; double grid; std::ofstream dump_file; @@ -47,6 +48,7 @@ struct QwpConfig QwpConfig() { ltr = false; alpha = false; + verbose = false; grid = 1.0 / 16; } }; @@ -211,10 +213,16 @@ struct QwpWorker // // M := [AA Ay] + if (config.verbose) + log("> System size: %d^2\n", GetSize(nodes)); + // Row major order int N = GetSize(nodes), N1 = N+1; vector<double> M(N * N1); + if (config.verbose) + log("> Edge constraints: %d\n", GetSize(edges)); + // Edge constraints: // A[i,:] := [ 0 0 .... 0 weight 0 ... 0 -weight 0 ... 0 0], y[i] := 0 // @@ -232,6 +240,9 @@ struct QwpWorker M[idx2 + idx1*N1] += -weight * weight; } + if (config.verbose) + log("> Node constraints: %d\n", GetSize(nodes)); + // Node constraints: // A[i,:] := [ 0 0 .... 0 weight 0 ... 0 0], y[i] := weight * pos // @@ -263,6 +274,9 @@ struct QwpWorker } #endif + if (config.verbose) + log("> Solving\n"); + // Solve "AA*x = Ay" // (least squares fit for "A*x = y") // @@ -277,6 +291,9 @@ struct QwpWorker // gaussian elimination for (int i = 0; i < N; i++) { + if (config.verbose && ((i+1) % (N/15)) == 0) + log("> Solved %d%%: %d/%d\n", (100*(i+1))/N, i+1, N); + // find best row int best_row = queue.front(); int best_row_queue_idx = 0; @@ -312,6 +329,9 @@ struct QwpWorker } } + if (config.verbose) + log("> Solved\n"); + log_assert(queue.empty()); log_assert(GetSize(pivot_cache) == N); @@ -334,6 +354,9 @@ struct QwpWorker } #endif + if (config.verbose) + log("> Update nodes\n"); + // update node positions for (int i = 0; i < N; i++) { @@ -778,6 +801,9 @@ struct QwpPass : public Pass { log(" -dump <html_file_name>\n"); log(" Dump a protocol of the placement algorithm to the html file.\n"); log("\n"); + log(" -v\n"); + log(" Verbose solver output for profiling or debugging\n"); + log("\n"); log("Note: This implementation of a quadratic wirelength placer uses exact\n"); log("dense matrix operations. It is only a toy-placer for small circuits.\n"); log("\n"); @@ -787,7 +813,7 @@ struct QwpPass : public Pass { QwpConfig config; xorshift32_state = 123456789; - log_header("Executing QWP pass (quadratic wirelength placer).\n"); + log_header(design, "Executing QWP pass (quadratic wirelength placer).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -799,6 +825,10 @@ struct QwpPass : public Pass { config.alpha = true; continue; } + if (args[argidx] == "-v") { + config.verbose = true; + continue; + } if (args[argidx] == "-grid" && argidx+1 < args.size()) { config.grid = 1.0 / atoi(args[++argidx].c_str()); continue; diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 532026f2..bb6d7447 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -181,10 +181,10 @@ struct SccWorker cell2scc[cell] = sccList.size(); scc.insert(cell); sccList.push_back(scc); - workQueue.erase(cell); log("\n"); - } else - run(cell, 0, maxDepth); + } + + run(cell, 0, maxDepth); } log("Found %d SCCs in module %s.\n", int(sccList.size()), RTLIL::id2cstr(module->name)); @@ -264,7 +264,7 @@ struct SccPass : public Pass { int maxDepth = -1; int expect = -1; - log_header("Executing SCC pass (detecting logic loops).\n"); + log_header(design, "Executing SCC pass (detecting logic loops).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 3e64dd84..d2e1a2e2 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -952,7 +952,7 @@ struct SelectPass : public Pass { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" select [ -add | -del | -set <name> ] {-read <filename> | <selection>}\n"); - log(" select [ -assert-none | -assert-any ] {-read <filename> | <selection>}\n"); + log(" select [ <assert_option> ] {-read <filename> | <selection>}\n"); log(" select [ -list | -write <filename> | -count | -clear ]\n"); log(" select -module <modname>\n"); log("\n"); @@ -988,6 +988,14 @@ struct SelectPass : public Pass { log(" do not modify the current selection. instead assert that the given\n"); log(" selection contains exactly N objects.\n"); log("\n"); + log(" -assert-max N\n"); + log(" do not modify the current selection. instead assert that the given\n"); + log(" selection contains less than or exactly N objects.\n"); + log("\n"); + log(" -assert-min N\n"); + log(" do not modify the current selection. instead assert that the given\n"); + log(" selection contains at least N objects.\n"); + log("\n"); log(" -list\n"); log(" list all objects in the current selection\n"); log("\n"); @@ -1168,6 +1176,8 @@ struct SelectPass : public Pass { bool assert_none = false; bool assert_any = false; int assert_count = -1; + int assert_max = -1; + int assert_min = -1; std::string write_file, read_file; std::string set_name, sel_str; @@ -1197,6 +1207,14 @@ struct SelectPass : public Pass { assert_count = atoi(args[++argidx].c_str()); continue; } + if (arg == "-assert-max" && argidx+1 < args.size()) { + assert_max = atoi(args[++argidx].c_str()); + continue; + } + if (arg == "-assert-min" && argidx+1 < args.size()) { + assert_min = atoi(args[++argidx].c_str()); + continue; + } if (arg == "-clear") { clear_mode = true; continue; @@ -1273,14 +1291,14 @@ struct SelectPass : public Pass { if (none_mode && args.size() != 2) log_cmd_error("Option -none can not be combined with any other options.\n"); - if (add_mode + del_mode + assert_none + assert_any + (assert_count >= 0) > 1) - log_cmd_error("Options -add, -del, -assert-none, -assert-any or -assert-count can not be combined.\n"); + if (add_mode + del_mode + assert_none + assert_any + (assert_count >= 0) + (assert_max >= 0) + (assert_min >= 0) > 1) + log_cmd_error("Options -add, -del, -assert-none, -assert-any, assert-count, -assert-max or -assert-min can not be combined.\n"); - if ((list_mode || !write_file.empty() || count_mode) && (add_mode || del_mode || assert_none || assert_any || assert_count >= 0)) - log_cmd_error("Options -list, -write and -count can not be combined with -add, -del, -assert-none, -assert-any or -assert-count.\n"); + if ((list_mode || !write_file.empty() || count_mode) && (add_mode || del_mode || assert_none || assert_any || assert_count >= 0 || assert_max >= 0 || assert_min >= 0)) + log_cmd_error("Options -list, -write and -count can not be combined with -add, -del, -assert-none, -assert-any, assert-count, -assert-max, or -assert-min.\n"); - if (!set_name.empty() && (list_mode || !write_file.empty() || count_mode || add_mode || del_mode || assert_none || assert_any || assert_count >= 0)) - log_cmd_error("Option -set can not be combined with -list, -write, -count, -add, -del, -assert-none, -assert-any or -assert-count.\n"); + if (!set_name.empty() && (list_mode || !write_file.empty() || count_mode || add_mode || del_mode || assert_none || assert_any || assert_count >= 0 || assert_max >= 0 || assert_min >= 0)) + log_cmd_error("Option -set can not be combined with -list, -write, -count, -add, -del, -assert-none, -assert-any, -assert-count, -assert-max, or -assert-min.\n"); if (work_stack.size() == 0 && got_module) { RTLIL::Selection sel; @@ -1385,7 +1403,7 @@ struct SelectPass : public Pass { return; } - if (assert_count >= 0) + if (assert_count >= 0 || assert_max >= 0 || assert_min >= 0) { int total_count = 0; if (work_stack.size() == 0) @@ -1407,9 +1425,15 @@ struct SelectPass : public Pass { if (sel->selected_member(mod_it.first, it.first)) total_count++; } - if (assert_count != total_count) + if (assert_count >= 0 && assert_count != total_count) log_error("Assertion failed: selection contains %d elements instead of the asserted %d:%s\n", total_count, assert_count, sel_str.c_str()); + if (assert_max >= 0 && assert_max < total_count) + log_error("Assertion failed: selection contains %d elements, more than the maximum number %d:%s\n", + total_count, assert_max, sel_str.c_str()); + if (assert_min >= 0 && assert_min > total_count) + log_error("Assertion failed: selection contains %d elements, less than the minimum number %d:%s\n", + total_count, assert_min, sel_str.c_str()); return; } diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index 75c738b6..9b05ae32 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -215,6 +215,12 @@ struct ChparamPass : public Pass { } break; } + + for (int i = argidx; i < GetSize(args); i++) + if (design->module("$abstract\\" + args[i]) != nullptr && + design->module(RTLIL::escape_id(args[i])) == nullptr) + args[i] = "$abstract\\" + args[i]; + extra_args(args, argidx, design); do_setunset(new_parameters, setunset_list); diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index 9ca2e874..26b2eb87 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -79,11 +79,15 @@ struct SetundefPass : public Pass { log(" replace with random bits using the specified integer als seed\n"); log(" value for the random number generator.\n"); log("\n"); + log(" -init\n"); + log(" also create/update init values for flip-flops\n"); + log("\n"); } virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { bool got_value = false; bool undriven_mode = false; + bool init_mode = false; SetundefWorker worker; size_t argidx; @@ -103,6 +107,10 @@ struct SetundefPass : public Pass { worker.next_bit_mode = 1; continue; } + if (args[argidx] == "-init") { + init_mode = true; + continue; + } if (args[argidx] == "-random" && !got_value && argidx+1 < args.size()) { got_value = true; worker.next_bit_mode = 2; @@ -118,12 +126,8 @@ struct SetundefPass : public Pass { if (!got_value) log_cmd_error("One of the options -zero, -one, or -random <seed> must be specified.\n"); - for (auto &mod_it : design->modules_) + for (auto module : design->selected_modules()) { - RTLIL::Module *module = mod_it.second; - if (!design->selected(module)) - continue; - if (undriven_mode) { if (!module->processes.empty()) @@ -151,6 +155,86 @@ struct SetundefPass : public Pass { } } + if (init_mode) + { + SigMap sigmap(module); + pool<SigBit> ffbits; + pool<Wire*> initwires; + + pool<IdString> fftypes; + fftypes.insert("$dff"); + fftypes.insert("$dffe"); + fftypes.insert("$dffsr"); + fftypes.insert("$adff"); + + std::vector<char> list_np = {'N', 'P'}, list_01 = {'0', '1'}; + + for (auto c1 : list_np) + fftypes.insert(stringf("$_DFF_%c_", c1)); + + for (auto c1 : list_np) + for (auto c2 : list_np) + fftypes.insert(stringf("$_DFFE_%c%c_", c1, c2)); + + for (auto c1 : list_np) + for (auto c2 : list_np) + for (auto c3 : list_01) + fftypes.insert(stringf("$_DFF_%c%c%c_", c1, c2, c3)); + + for (auto c1 : list_np) + for (auto c2 : list_np) + for (auto c3 : list_np) + fftypes.insert(stringf("$_DFFSR_%c%c%c_", c1, c2, c3)); + + for (auto cell : module->cells()) + { + if (!fftypes.count(cell->type)) + continue; + + for (auto bit : sigmap(cell->getPort("\\Q"))) + ffbits.insert(bit); + } + + for (auto wire : module->wires()) + { + if (!wire->attributes.count("\\init")) + continue; + + for (auto bit : sigmap(wire)) + ffbits.erase(bit); + + initwires.insert(wire); + } + + for (int wire_types = 0; wire_types < 2; wire_types++) + for (auto wire : module->wires()) + { + if (wire->name[0] == (wire_types ? '\\' : '$')) + next_wire: + continue; + + for (auto bit : sigmap(wire)) + if (!ffbits.count(bit)) + goto next_wire; + + for (auto bit : sigmap(wire)) + ffbits.erase(bit); + + initwires.insert(wire); + } + + for (auto wire : initwires) + { + Const &initval = wire->attributes["\\init"]; + + for (int i = 0; i < GetSize(wire); i++) + if (GetSize(initval) <= i) + initval.bits.push_back(worker.next_bit()); + else if (initval.bits[i] == State::Sx) + initval.bits[i] = worker.next_bit(); + } + } + module->rewrite_sigspecs(worker); } } diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 3b03d680..3a3939a8 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -582,8 +582,9 @@ struct ShowPass : public Pass { log(" Run the specified command with the graphics file as parameter.\n"); log("\n"); log(" -format <format>\n"); - log(" Generate a graphics file in the specified format.\n"); - log(" Usually <format> is 'svg' or 'ps'.\n"); + log(" Generate a graphics file in the specified format. Use 'dot' to just\n"); + log(" generate a .dot file, or other <format> strings such as 'svg' or 'ps'\n"); + log(" to generate files in other formats (this calls the 'dot' command).\n"); log("\n"); log(" -lib <verilog_or_ilang_file>\n"); log(" Use the specified library file for determining whether cell ports are\n"); @@ -646,12 +647,13 @@ struct ShowPass : public Pass { log("unless another prefix is specified using -prefix <prefix>.\n"); log("\n"); log("Yosys on Windows and YosysJS use different defaults: The output is written\n"); - log("to 'show.dot' in the current directory and new viewer is launched.\n"); + log("to 'show.dot' in the current directory and new viewer is launched each time\n"); + log("the 'show' command is executed.\n"); log("\n"); } virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { - log_header("Generating Graphviz representation of design.\n"); + log_header(design, "Generating Graphviz representation of design.\n"); log_push(); std::vector<std::pair<std::string, RTLIL::Selection>> color_selections; @@ -759,7 +761,7 @@ struct ShowPass : public Pass { } extra_args(args, argidx, design); - if (format != "ps") { + if (format != "ps" && format != "dot") { int modcount = 0; for (auto &mod_it : design->modules_) { if (mod_it.second->get_bool_attribute("\\blackbox")) @@ -770,7 +772,7 @@ struct ShowPass : public Pass { modcount++; } if (modcount > 1) - log_cmd_error("For formats different than 'ps' only one module must be selected.\n"); + log_cmd_error("For formats different than 'ps' or 'dot' only one module must be selected.\n"); } for (auto filename : libfiles) { @@ -784,7 +786,7 @@ struct ShowPass : public Pass { } if (libs.size() > 0) - log_header("Continuing show pass.\n"); + log_header(design, "Continuing show pass.\n"); std::string dot_file = stringf("%s.dot", prefix.c_str()); std::string out_file = stringf("%s.%s", prefix.c_str(), format.empty() ? "svg" : format.c_str()); @@ -806,7 +808,7 @@ struct ShowPass : public Pass { log_cmd_error("Nothing there to show.\n"); if (format != "dot" && !format.empty()) { - std::string cmd = stringf("dot -T%s -o '%s.new' '%s' && mv '%s.new' '%s'", format.c_str(), out_file.c_str(), dot_file.c_str(), out_file.c_str(), out_file.c_str()); + std::string cmd = stringf("dot -T%s '%s' > '%s.new' && mv '%s.new' '%s'", format.c_str(), dot_file.c_str(), out_file.c_str(), out_file.c_str(), out_file.c_str()); log("Exec: %s\n", cmd.c_str()); if (run_command(cmd) != 0) log_cmd_error("Shell command failed!\n"); diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index 2556fb74..7418ec4d 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -341,7 +341,7 @@ struct SplicePass : public Pass { if (!ports.empty() && !no_ports.empty()) log_cmd_error("The options -port and -no_port are exclusive!\n"); - log_header("Executing SPLICE pass (creating cells for signal splicing).\n"); + log_header(design, "Executing SPLICE pass (creating cells for signal splicing).\n"); for (auto &mod_it : design->modules_) { diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index 0d7892d7..14eeb066 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -109,7 +109,7 @@ struct SplitnetsPass : public Pass { bool flag_driver = false; std::string format = "[]:"; - log_header("Executing SPLITNETS pass (splitting up multi-bit signals).\n"); + log_header(design, "Executing SPLITNETS pass (splitting up multi-bit signals).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 048933fc..362a0edf 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -232,7 +232,7 @@ struct StatPass : public Pass { } virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { - log_header("Printing statistics.\n"); + log_header(design, "Printing statistics.\n"); bool width_mode = false; RTLIL::Module *top_mod = NULL; diff --git a/passes/cmds/tee.cc b/passes/cmds/tee.cc index a0484090..3db2dbf0 100644 --- a/passes/cmds/tee.cc +++ b/passes/cmds/tee.cc @@ -45,10 +45,14 @@ struct TeePass : public Pass { log(" -a logfile\n"); log(" Write output to this file, append if exists.\n"); log("\n"); + log(" +INT, -INT\n"); + log(" Add/subract INT from the -v setting for this command.\n"); + log("\n"); } virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { std::vector<FILE*> backup_log_files, files_to_close; + int backup_log_verbose_level = log_verbose_level; backup_log_files = log_files; size_t argidx; @@ -70,6 +74,10 @@ struct TeePass : public Pass { files_to_close.push_back(f); continue; } + if (GetSize(args[argidx]) >= 2 && (args[argidx][0] == '-' || args[argidx][0] == '+') && args[argidx][1] >= '0' && args[argidx][1] <= '9') { + log_verbose_level += atoi(args[argidx].c_str()); + continue; + } break; } @@ -85,6 +93,8 @@ struct TeePass : public Pass { for (auto cf : files_to_close) fclose(cf); + + log_verbose_level = backup_log_verbose_level; log_files = backup_log_files; } } TeePass; diff --git a/passes/cmds/torder.cc b/passes/cmds/torder.cc index 50317c02..56223610 100644 --- a/passes/cmds/torder.cc +++ b/passes/cmds/torder.cc @@ -48,7 +48,7 @@ struct TorderPass : public Pass { bool noautostop = false; dict<IdString, pool<IdString>> stop_db; - log_header("Executing TORDER pass (print cells in topological order).\n"); + log_header(design, "Executing TORDER pass (print cells in topological order).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { |