diff options
author | Ruben Undheim <ruben.undheim@gmail.com> | 2016-11-03 23:18:00 +0100 |
---|---|---|
committer | Ruben Undheim <ruben.undheim@gmail.com> | 2016-11-03 23:18:00 +0100 |
commit | fefe0fc0430f4f173a25e674708aa0f4f0854b31 (patch) | |
tree | adb13b830212c269d58031f900d652f29013d2d7 /passes/fsm | |
parent | 4f096fe65b77435daba019248273e547fa18d167 (diff) |
Imported yosys 0.7
Diffstat (limited to 'passes/fsm')
-rw-r--r-- | passes/fsm/fsm.cc | 12 | ||||
-rw-r--r-- | passes/fsm/fsm_expand.cc | 40 | ||||
-rw-r--r-- | passes/fsm/fsm_map.cc | 3 | ||||
-rw-r--r-- | passes/fsm/fsm_recode.cc | 6 |
4 files changed, 40 insertions, 21 deletions
diff --git a/passes/fsm/fsm.cc b/passes/fsm/fsm.cc index 3b537ecd..997558b8 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 3ded3f37..e7b9dcf9 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<RTLIL::Cell*, RTLIL::sort_by_name_id<RTLIL::Cell>> 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<std::string> 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(); } } diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index 5b32ed59..c4230375 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -272,7 +272,8 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) } else { - RTLIL::SigSpec sig_a, sig_b, sig_s; + RTLIL::SigSpec sig_a(RTLIL::State::Sx, next_state_wire->width); + RTLIL::SigSpec sig_b, sig_s; int reset_state = fsm_data.reset_state; if (reset_state < 0) reset_state = 0; diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index 5102d833..e1bde728 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -57,13 +57,13 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs log("Recoding FSM `%s' from module `%s' using `%s' encoding:\n", cell->name.c_str(), module->name.c_str(), encoding.c_str()); - if (encoding != "none" && encoding != "one-hot" && encoding != "binary" && encoding != "auto") { + if (encoding != "none" && encoding != "user" && encoding != "one-hot" && encoding != "binary" && encoding != "auto") { log(" unknown encoding `%s': using auto instead.\n", encoding.c_str()); encoding = "auto"; } - if (encoding == "none") { - log(" nothing to do for encoding `none'.\n"); + if (encoding == "none" || encoding == "user") { + log(" nothing to do for encoding `%s'.\n", encoding.c_str()); return; } |