diff --git a/passes/fsm/fsm.cc b/passes/fsm/fsm.cc index 3b537ecd8..997558b85 100644 --- a/passes/fsm/fsm.cc +++ b/passes/fsm/fsm.cc @@ -59,6 +59,9 @@ struct FsmPass : public Pass { log(" -expand, -norecode, -export, -nomap\n"); log(" enable or disable passes as indicated above\n"); log("\n"); + log(" -fullexpand\n"); + log(" call expand with -full option\n"); + log("\n"); log(" -encoding type\n"); log(" -fm_set_fsm_file file\n"); log(" -encfile file\n"); @@ -71,6 +74,7 @@ struct FsmPass : public Pass { bool flag_norecode = false; bool flag_nodetect = false; bool flag_expand = false; + bool flag_fullexpand = false; bool flag_export = false; std::string fm_set_fsm_file_opt; std::string encfile_opt; @@ -110,6 +114,10 @@ struct FsmPass : public Pass { flag_expand = true; continue; } + if (arg == "-fullexpand") { + flag_fullexpand = true; + continue; + } if (arg == "-export") { flag_export = true; continue; @@ -126,8 +134,8 @@ struct FsmPass : public Pass { Pass::call(design, "opt_clean"); Pass::call(design, "fsm_opt"); - if (flag_expand) { - Pass::call(design, "fsm_expand"); + if (flag_expand || flag_fullexpand) { + Pass::call(design, flag_fullexpand ? "fsm_expand -full" : "fsm_expand"); Pass::call(design, "opt_clean"); Pass::call(design, "fsm_opt"); } diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index 3ded3f377..e7b9dcf90 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -32,6 +32,8 @@ struct FsmExpand { RTLIL::Module *module; RTLIL::Cell *fsm_cell; + bool full_mode; + SigMap assign_map; SigSet> sig2driver, sig2user; CellTypes ct; @@ -45,6 +47,9 @@ struct FsmExpand bool is_cell_merge_candidate(RTLIL::Cell *cell) { + if (full_mode || cell->type == "$_MUX_") + return true; + if (cell->type == "$mux" || cell->type == "$pmux") if (cell->getPort("\\A").size() < 2) return true; @@ -68,17 +73,6 @@ struct FsmExpand if (new_signals.size() > 3) return false; - if (cell->hasPort("\\Y")) { - new_signals.append(assign_map(cell->getPort("\\Y"))); - new_signals.sort_and_unify(); - new_signals.remove_const(); - new_signals.remove(assign_map(fsm_cell->getPort("\\CTRL_IN"))); - new_signals.remove(assign_map(fsm_cell->getPort("\\CTRL_OUT"))); - } - - if (new_signals.size() > 2) - return false; - return true; } @@ -200,13 +194,15 @@ struct FsmExpand fsm_data.copy_to_cell(fsm_cell); } - FsmExpand(RTLIL::Cell *cell, RTLIL::Design *design, RTLIL::Module *mod) + FsmExpand(RTLIL::Cell *cell, RTLIL::Design *design, RTLIL::Module *mod, bool full) { module = mod; fsm_cell = cell; + full_mode = full; assign_map.set(module); ct.setup_internals(); + ct.setup_stdcells(); for (auto &cell_it : module->cells_) { RTLIL::Cell *c = cell_it.second; @@ -249,17 +245,31 @@ struct FsmExpandPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" fsm_expand [selection]\n"); + log(" fsm_expand [-full] [selection]\n"); log("\n"); log("The fsm_extract pass is conservative about the cells that belong to a finite\n"); log("state machine. This pass can be used to merge additional auxiliary gates into\n"); log("the finite state machine.\n"); log("\n"); + log("By default, fsm_expand is still a bit conservative regarding merging larger\n"); + log("word-wide cells. Call with -full to consider all cells for merging.\n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { + bool full_mode = false; + log_header(design, "Executing FSM_EXPAND pass (merging auxiliary logic into FSMs).\n"); - extra_args(args, 1, design); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-full") { + full_mode = true; + continue; + } + break; + } + extra_args(args, argidx, design); for (auto &mod_it : design->modules_) { if (!design->selected(mod_it.second)) @@ -269,7 +279,7 @@ struct FsmExpandPass : public Pass { 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, design, mod_it.second); + FsmExpand fsm_expand(c, design, mod_it.second, full_mode); fsm_expand.execute(); } }