aboutsummaryrefslogtreecommitdiffstats
path: root/passes/fsm/fsm_map.cc
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2014-08-09 14:49:51 +0200
committerClifford Wolf <clifford@clifford.at>2014-08-09 14:49:51 +0200
commit2faef8973830e553b1730c07d327c8d76d412e1c (patch)
tree5ad43e1f7d86c4c257a1b111e342ccd2b70e0d87 /passes/fsm/fsm_map.cc
parent51aa5544fbda97c6b49bfba55696083ba47d4cef (diff)
downloadyosys-2faef8973830e553b1730c07d327c8d76d412e1c.tar.gz
yosys-2faef8973830e553b1730c07d327c8d76d412e1c.tar.bz2
yosys-2faef8973830e553b1730c07d327c8d76d412e1c.zip
Some improvements in fsm_opt and fsm_map for FSM with unreachable states
Diffstat (limited to 'passes/fsm/fsm_map.cc')
-rw-r--r--passes/fsm/fsm_map.cc107
1 files changed, 57 insertions, 50 deletions
diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc
index 99b736c1b..b3750de08 100644
--- a/passes/fsm/fsm_map.cc
+++ b/passes/fsm/fsm_map.cc
@@ -207,65 +207,72 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module)
// generate next_state signal
- RTLIL::Wire *next_state_onehot = module->addWire(NEW_ID, fsm_data.state_table.size());
-
- for (size_t i = 0; i < fsm_data.state_table.size(); i++)
+ if (SIZE(fsm_data.state_table) == 1)
{
- std::map<RTLIL::Const, std::set<int>> pattern_cache;
- std::set<int> fullstate_cache;
+ module->connect(next_state_wire, fsm_data.state_table.front());
+ }
+ else
+ {
+ RTLIL::Wire *next_state_onehot = module->addWire(NEW_ID, fsm_data.state_table.size());
- for (size_t j = 0; j < fsm_data.state_table.size(); j++)
- fullstate_cache.insert(j);
+ for (size_t i = 0; i < fsm_data.state_table.size(); i++)
+ {
+ std::map<RTLIL::Const, std::set<int>> pattern_cache;
+ std::set<int> fullstate_cache;
- for (auto &tr : fsm_data.transition_table) {
- if (tr.state_out == int(i))
- pattern_cache[tr.ctrl_in].insert(tr.state_in);
- else
- fullstate_cache.erase(tr.state_in);
- }
+ for (size_t j = 0; j < fsm_data.state_table.size(); j++)
+ fullstate_cache.insert(j);
- implement_pattern_cache(module, pattern_cache, fullstate_cache, fsm_data.state_table.size(), state_onehot, ctrl_in, RTLIL::SigSpec(next_state_onehot, i));
- }
+ for (auto &tr : fsm_data.transition_table) {
+ if (tr.state_out == int(i))
+ pattern_cache[tr.ctrl_in].insert(tr.state_in);
+ else
+ fullstate_cache.erase(tr.state_in);
+ }
- if (encoding_is_onehot)
- {
- RTLIL::SigSpec next_state_sig(RTLIL::State::Sm, next_state_wire->width);
- for (size_t i = 0; i < fsm_data.state_table.size(); i++) {
- RTLIL::Const state = fsm_data.state_table[i];
- int bit_idx = -1;
- for (size_t j = 0; j < state.bits.size(); j++)
- if (state.bits[j] == RTLIL::State::S1)
- bit_idx = j;
- if (bit_idx >= 0)
- next_state_sig.replace(bit_idx, RTLIL::SigSpec(next_state_onehot, i));
+ implement_pattern_cache(module, pattern_cache, fullstate_cache, fsm_data.state_table.size(), state_onehot, ctrl_in, RTLIL::SigSpec(next_state_onehot, i));
}
- log_assert(!next_state_sig.has_marked_bits());
- module->connect(RTLIL::SigSig(next_state_wire, next_state_sig));
- }
- else
- {
- RTLIL::SigSpec sig_a, sig_b, sig_s;
- int reset_state = fsm_data.reset_state;
- if (reset_state < 0)
- reset_state = 0;
-
- for (size_t i = 0; i < fsm_data.state_table.size(); i++) {
- RTLIL::Const state = fsm_data.state_table[i];
- if (int(i) == fsm_data.reset_state) {
- sig_a = RTLIL::SigSpec(state);
- } else {
- sig_b.append(RTLIL::SigSpec(state));
- sig_s.append(RTLIL::SigSpec(next_state_onehot, i));
+
+ if (encoding_is_onehot)
+ {
+ RTLIL::SigSpec next_state_sig(RTLIL::State::Sm, next_state_wire->width);
+ for (size_t i = 0; i < fsm_data.state_table.size(); i++) {
+ RTLIL::Const state = fsm_data.state_table[i];
+ int bit_idx = -1;
+ for (size_t j = 0; j < state.bits.size(); j++)
+ if (state.bits[j] == RTLIL::State::S1)
+ bit_idx = j;
+ if (bit_idx >= 0)
+ next_state_sig.replace(bit_idx, RTLIL::SigSpec(next_state_onehot, i));
}
+ log_assert(!next_state_sig.has_marked_bits());
+ module->connect(RTLIL::SigSig(next_state_wire, next_state_sig));
}
+ else
+ {
+ RTLIL::SigSpec sig_a, sig_b, sig_s;
+ int reset_state = fsm_data.reset_state;
+ if (reset_state < 0)
+ reset_state = 0;
+
+ for (size_t i = 0; i < fsm_data.state_table.size(); i++) {
+ RTLIL::Const state = fsm_data.state_table[i];
+ if (int(i) == fsm_data.reset_state) {
+ sig_a = RTLIL::SigSpec(state);
+ } else {
+ sig_b.append(RTLIL::SigSpec(state));
+ sig_s.append(RTLIL::SigSpec(next_state_onehot, i));
+ }
+ }
- RTLIL::Cell *mux_cell = module->addCell(NEW_ID, "$safe_pmux");
- mux_cell->setPort("\\A", sig_a);
- mux_cell->setPort("\\B", sig_b);
- mux_cell->setPort("\\S", sig_s);
- mux_cell->setPort("\\Y", RTLIL::SigSpec(next_state_wire));
- mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.size());
- mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.size());
+ RTLIL::Cell *mux_cell = module->addCell(NEW_ID, "$safe_pmux");
+ mux_cell->setPort("\\A", sig_a);
+ mux_cell->setPort("\\B", sig_b);
+ mux_cell->setPort("\\S", sig_s);
+ mux_cell->setPort("\\Y", RTLIL::SigSpec(next_state_wire));
+ mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.size());
+ mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.size());
+ }
}
// Generate ctrl_out signal