summaryrefslogtreecommitdiff
path: root/passes/fsm
diff options
context:
space:
mode:
authorRuben Undheim <ruben.undheim@gmail.com>2016-11-03 23:18:00 +0100
committerRuben Undheim <ruben.undheim@gmail.com>2016-11-03 23:18:00 +0100
commitfefe0fc0430f4f173a25e674708aa0f4f0854b31 (patch)
treeadb13b830212c269d58031f900d652f29013d2d7 /passes/fsm
parent4f096fe65b77435daba019248273e547fa18d167 (diff)
Imported yosys 0.7
Diffstat (limited to 'passes/fsm')
-rw-r--r--passes/fsm/fsm.cc12
-rw-r--r--passes/fsm/fsm_expand.cc40
-rw-r--r--passes/fsm/fsm_map.cc3
-rw-r--r--passes/fsm/fsm_recode.cc6
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;
}