diff options
-rw-r--r-- | passes/fsm/fsm.cc | 38 | ||||
-rw-r--r-- | passes/fsm/fsm_detect.cc | 24 | ||||
-rw-r--r-- | passes/fsm/fsm_expand.cc | 25 | ||||
-rw-r--r-- | passes/fsm/fsm_export.cc | 31 | ||||
-rw-r--r-- | passes/fsm/fsm_extract.cc | 24 | ||||
-rw-r--r-- | passes/fsm/fsm_info.cc | 30 | ||||
-rw-r--r-- | passes/fsm/fsm_map.cc | 17 | ||||
-rw-r--r-- | passes/fsm/fsm_opt.cc | 22 | ||||
-rw-r--r-- | passes/fsm/fsm_recode.cc | 23 | ||||
-rw-r--r-- | passes/opt/opt.cc | 2 |
10 files changed, 194 insertions, 42 deletions
diff --git a/passes/fsm/fsm.cc b/passes/fsm/fsm.cc index 61322fbd3..c0c42de9f 100644 --- a/passes/fsm/fsm.cc +++ b/passes/fsm/fsm.cc @@ -23,7 +23,43 @@ #include <stdio.h> struct FsmPass : public Pass { - FsmPass() : Pass("fsm") { } + FsmPass() : Pass("fsm", "extract and optimize finite state machines") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" fsm [options] [selection]\n"); + log("\n"); + log("This pass calls all the other fsm_* passes in a useful order. This performs\n"); + log("FSM extraction and optimiziation. It also calls opt_rmunused as needed:\n"); + log("\n"); + log(" fsm_detect\n"); + log(" fsm_extract\n"); + log("\n"); + log(" fsm_opt\n"); + log(" opt_rmunused\n"); + log(" fsm_opt\n"); + log("\n"); + log(" fsm_expand if got option -expand\n"); + log(" opt_rmunused if got option -expand\n"); + log(" fsm_opt if got option -expand\n"); + log("\n"); + log(" fsm_recode unless got option -norecode\n"); + log("\n"); + log(" fsm_info\n"); + log("\n"); + log(" fsm_export if got option -export\n"); + log(" fsm_map unless got option -nomap\n"); + log("\n"); + log("Options:\n"); + log("\n"); + log(" -expand, -norecode, -export, -nomap\n"); + log(" enable or disable passes as indicated above\n"); + log("\n"); + log(" -fm_set_fsm_file file\n"); + log(" passed through to fsm_recode pass\n"); + log("\n"); + } virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { bool flag_nomap = false; diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index 067ed171f..f20675ff7 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -109,7 +109,23 @@ static void detect_fsm(RTLIL::Wire *wire) } struct FsmDetectPass : public Pass { - FsmDetectPass() : Pass("fsm_detect") { } + FsmDetectPass() : Pass("fsm_detect", "finding FSMs in design") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" fsm_detect [selection]\n"); + log("\n"); + log("This pass detects finite state machine by identifying the state signal.\n"); + log("The state signal is then marked by setting the attribute 'fsm_encoding'\n"); + log("on the state signal to \"auto\".\n"); + log("\n"); + log("Existing 'fsm_encoding' attributes are not changed by this pass.\n"); + log("\n"); + log("Signals can be protected from beeing detected by this pass by setting the\n"); + log("'fsm_encoding' atrribute to \"none\".\n"); + log("\n"); + } virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { log_header("Executing FSM_DETECT pass (finding FSMs in design).\n"); @@ -123,6 +139,9 @@ struct FsmDetectPass : public Pass { for (auto &mod_it : design->modules) { + if (!design->selected(mod_it.second)) + continue; + module = mod_it.second; assign_map.set(module); @@ -148,7 +167,8 @@ struct FsmDetectPass : public Pass { sig_at_port.add(assign_map(RTLIL::SigSpec(wire_it.second))); for (auto &wire_it : module->wires) - detect_fsm(wire_it.second); + if (design->selected(module, wire_it.second)) + detect_fsm(wire_it.second); } assign_map.clear(); diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index 0d5bc7695..e6829f49e 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -188,7 +188,7 @@ struct FsmExpand fsm_data.copy_to_cell(fsm_cell); } - FsmExpand(RTLIL::Cell *cell, RTLIL::Module *mod) + FsmExpand(RTLIL::Cell *cell, RTLIL::Design *design, RTLIL::Module *mod) { module = mod; fsm_cell = cell; @@ -198,7 +198,7 @@ struct FsmExpand for (auto &cell_it : module->cells) { RTLIL::Cell *c = cell_it.second; - if (ct.cell_known(c->type)) + if (ct.cell_known(c->type) && design->selected(mod, c)) for (auto &p : c->connections) { if (ct.cell_output(c->type, p.first)) sig2driver.insert(assign_map(p.second), c); @@ -234,19 +234,32 @@ struct FsmExpand }; struct FsmExpandPass : public Pass { - FsmExpandPass() : Pass("fsm_expand") { } + FsmExpandPass() : Pass("fsm_expand", "expand FSM cells by merging logic into it") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" fsm_expand [selection]\n"); + log("\n"); + log("The fsm_extract pass is conservative about the cells that belong the a finate\n"); + log("state machine. This pass can be used to merge additional auxiliary gates into\n"); + log("the finate state machine.\n"); + log("\n"); + } virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { - log_header("Executing FSM_EXPAND pass (re-assigning FSM state encoding).\n"); + log_header("Executing FSM_EXPAND pass (merging auxiliary logic into FSMs).\n"); extra_args(args, 1, design); for (auto &mod_it : design->modules) { + if (!design->selected(mod_it.second)) + continue; std::vector<RTLIL::Cell*> fsm_cells; for (auto &cell_it : mod_it.second->cells) - if (cell_it.second->type == "$fsm") + if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) fsm_cells.push_back(cell_it.second); for (auto c : fsm_cells) { - FsmExpand fsm_expand(c, mod_it.second); + FsmExpand fsm_expand(c, design, mod_it.second); fsm_expand.execute(); } } diff --git a/passes/fsm/fsm_export.cc b/passes/fsm/fsm_export.cc index aa049445c..26d120a16 100644 --- a/passes/fsm/fsm_export.cc +++ b/passes/fsm/fsm_export.cc @@ -109,9 +109,21 @@ void write_kiss2(struct RTLIL::Module *module, struct RTLIL::Cell *cell) { * only the KISS2 file format is supported. */ struct FsmExportPass : public Pass { - FsmExportPass() : Pass("fsm_export") { + FsmExportPass() : Pass("fsm_export", "exporting FSMs to KISS2 files") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" fsm_export [-noauto] [selection]\n"); + log("\n"); + log("This pass creates a KISS2 file for every selected FSM. For FSMs with the\n"); + log("'fsm_export' attribute set, the attribute value is used as filename, otherwise\n"); + log("the module and cell name is used as filename.\n"); + log("\n"); + log(" -noauto\n"); + log(" only export FSMs that have the 'fsm_export' attribute set\n"); + log("\n"); } - virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { std::map<RTLIL::IdString, RTLIL::Const>::iterator attr_it; @@ -132,12 +144,13 @@ struct FsmExportPass : public Pass { extra_args(args, argidx, design); for (auto &mod_it : design->modules) - for (auto &cell_it : mod_it.second->cells) - if (cell_it.second->type == "$fsm") { - attr_it = cell_it.second->attributes.find("\\fsm_export"); - if (!flag_noauto || (attr_it != cell_it.second->attributes.end())) { - write_kiss2(mod_it.second, cell_it.second); - } - } + if (design->selected(mod_it.second)) + for (auto &cell_it : mod_it.second->cells) + if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) { + attr_it = cell_it.second->attributes.find("\\fsm_export"); + if (!flag_noauto || (attr_it != cell_it.second->attributes.end())) { + write_kiss2(mod_it.second, cell_it.second); + } + } } } FsmExportPass; diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index c89078cd3..4971e4c19 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -310,7 +310,23 @@ static void extract_fsm(RTLIL::Wire *wire) } struct FsmExtractPass : public Pass { - FsmExtractPass() : Pass("fsm_extract") { } + FsmExtractPass() : Pass("fsm_extract", "extracting FSMs in design") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" fsm_extract [selection]\n"); + log("\n"); + log("This pass operates on all signals marked as FSM state signals using the\n"); + log("'fsm_encoding' attribute. It consumes the logic that creates the state signal\n"); + log("and uses the state signal to generate control signal and replaces it with an\n"); + log("FSM cell.\n"); + log("\n"); + log("The generated FSM cell still generates the original state signal with its\n"); + log("original encoding. The 'fsm_opt' pass can be used in combination with the\n"); + log("'opt_rmunused' pass to eliminate this signal.\n"); + log("\n"); + } virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { log_header("Executing FSM_EXTRACT pass (extracting FSM from design).\n"); @@ -324,6 +340,9 @@ struct FsmExtractPass : public Pass { for (auto &mod_it : design->modules) { + if (!design->selected(mod_it.second)) + continue; + module = mod_it.second; assign_map.set(module); @@ -347,7 +366,8 @@ struct FsmExtractPass : public Pass { std::vector<RTLIL::Wire*> wire_list; for (auto &wire_it : module->wires) if (wire_it.second->attributes.count("\\fsm_encoding") > 0 && wire_it.second->attributes["\\fsm_encoding"].str != "none") - wire_list.push_back(wire_it.second); + if (design->selected(module, wire_it.second)) + wire_list.push_back(wire_it.second); for (auto wire : wire_list) extract_fsm(wire); } diff --git a/passes/fsm/fsm_info.cc b/passes/fsm/fsm_info.cc index 83f065760..f2d0c1a81 100644 --- a/passes/fsm/fsm_info.cc +++ b/passes/fsm/fsm_info.cc @@ -26,21 +26,33 @@ #include <string.h> struct FsmInfoPass : public Pass { - FsmInfoPass() : Pass("fsm_info") { } + FsmInfoPass() : Pass("fsm_info", "print information on finite state machines") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" fsm_info [selection]\n"); + log("\n"); + log("This pass dumps all internal information on FSM cells. It can be useful for\n"); + log("analyzing the synthesis process and is called automatically by the 'fsm'\n"); + log("pass so that this information is included in the synthesis log file.\n"); + log("\n"); + } virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { log_header("Executing FSM_INFO pass (dumping all available information on FSM cells).\n"); extra_args(args, 1, design); for (auto &mod_it : design->modules) - for (auto &cell_it : mod_it.second->cells) - if (cell_it.second->type == "$fsm") { - log("\n"); - log("FSM `%s' from module `%s':\n", cell_it.second->name.c_str(), mod_it.first.c_str()); - FsmData fsm_data; - fsm_data.copy_from_cell(cell_it.second); - fsm_data.log_info(cell_it.second); - } + if (design->selected(mod_it.second)) + for (auto &cell_it : mod_it.second->cells) + if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) { + log("\n"); + log("FSM `%s' from module `%s':\n", cell_it.second->name.c_str(), mod_it.first.c_str()); + FsmData fsm_data; + fsm_data.copy_from_cell(cell_it.second); + fsm_data.log_info(cell_it.second); + } } } FsmInfoPass; diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index 4319dc044..063af587d 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -337,16 +337,27 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) } struct FsmMapPass : public Pass { - FsmMapPass() : Pass("fsm_map") { } + FsmMapPass() : Pass("fsm_map", "mapping FSMs to basic logic") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" fsm_map [selection]\n"); + log("\n"); + log("This pass translates FSM cells to flip-flops and logic.\n"); + log("\n"); + } virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { - log_header("Executing FSM_MAP pass (simple optimizations of FSMs).\n"); + log_header("Executing FSM_MAP pass (mapping FSMs to basic logic).\n"); extra_args(args, 1, design); for (auto &mod_it : design->modules) { + if (!design->selected(mod_it.second)) + continue; std::vector<RTLIL::Cell*> fsm_cells; for (auto &cell_it : mod_it.second->cells) - if (cell_it.second->type == "$fsm") + if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) fsm_cells.push_back(cell_it.second); for (auto cell : fsm_cells) map_fsm(cell, mod_it.second); diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc index 8ba9679fd..ae764eaa5 100644 --- a/passes/fsm/fsm_opt.cc +++ b/passes/fsm/fsm_opt.cc @@ -269,16 +269,28 @@ void FsmData::optimize_fsm(RTLIL::Cell *cell, RTLIL::Module *module) } struct FsmOptPass : public Pass { - FsmOptPass() : Pass("fsm_opt") { } + FsmOptPass() : Pass("fsm_opt", "optimize finite state machines") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" fsm_opt [selection]\n"); + log("\n"); + log("This pass optimizes FSM cells. It detects which output signals are actually\n"); + log("not used and removes them from the FSM. This pass is usually used in\n"); + log("combination with the 'opt_rmunused' pass (see also 'help fsm').\n"); + log("\n"); + } virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { log_header("Executing FSM_OPT pass (simple optimizations of FSMs).\n"); extra_args(args, 1, design); - for (auto &mod_it : design->modules) - for (auto &cell_it : mod_it.second->cells) { - if (cell_it.second->type == "$fsm") - FsmData::optimize_fsm(cell_it.second, mod_it.second); + for (auto &mod_it : design->modules) { + if (design->selected(mod_it.second)) + for (auto &cell_it : mod_it.second->cells) + if (cell_it.second->type == "$fsm" and design->selected(mod_it.second, cell_it.second)) + FsmData::optimize_fsm(cell_it.second, mod_it.second); } } } FsmOptPass; diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index 5e258f269..acb5944a1 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -83,7 +83,21 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs } struct FsmRecodePass : public Pass { - FsmRecodePass() : Pass("fsm_recode") { } + FsmRecodePass() : Pass("fsm_recode", "recoding finite state machines") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" fsm_recode [-fm_set_fsm_file file] [selection]\n"); + log("\n"); + log("This pass reassign the state encodings for FSM cells. At the moment only\n"); + log("one-hot encoding is supported.\n"); + log("\n"); + log("The option -fm_set_fsm_file can be used to generate a file containing the\n"); + log("mapping from old to new FSM encoding in form of Synopsys Formality set_fsm_*\n"); + log("commands.\n"); + log("\n"); + } virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { FILE *fm_set_fsm_file = NULL; @@ -103,9 +117,10 @@ struct FsmRecodePass : public Pass { extra_args(args, argidx, design); for (auto &mod_it : design->modules) - for (auto &cell_it : mod_it.second->cells) - if (cell_it.second->type == "$fsm") - fsm_recode(cell_it.second, mod_it.second, fm_set_fsm_file); + if (design->selected(mod_it.second)) + for (auto &cell_it : mod_it.second->cells) + if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) + fsm_recode(cell_it.second, mod_it.second, fm_set_fsm_file); if (fm_set_fsm_file != NULL) fclose(fm_set_fsm_file); diff --git a/passes/opt/opt.cc b/passes/opt/opt.cc index b742a0951..ea1c95705 100644 --- a/passes/opt/opt.cc +++ b/passes/opt/opt.cc @@ -33,7 +33,7 @@ struct OptPass : public Pass { log("\n"); log(" opt [selection]\n"); log("\n"); - log("This pass calls all the other opt_* passes in a useful manner. This performs\n"); + log("This pass calls all the other opt_* passes in a useful order. This performs\n"); log("a series of trivial optimizations and cleanups. This pass executes the other\n"); log("passes in the following order:\n"); log("\n"); |