Some improvements in fsm_opt and fsm_map for FSM with unreachable states

This commit is contained in:
Clifford Wolf 2014-08-09 14:49:51 +02:00
parent 51aa5544fb
commit 2faef89738
3 changed files with 104 additions and 52 deletions

View File

@ -207,6 +207,12 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module)
// generate next_state signal
if (SIZE(fsm_data.state_table) == 1)
{
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 i = 0; i < fsm_data.state_table.size(); i++)
@ -267,6 +273,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module)
mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.size());
mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.size());
}
}
// Generate ctrl_out signal

View File

@ -31,6 +31,48 @@ struct FsmOpt
RTLIL::Cell *cell;
RTLIL::Module *module;
void opt_unreachable_states()
{
while (1)
{
std::set<int> unreachable_states;
std::vector<FsmData::transition_t> new_transition_table;
std::vector<RTLIL::Const> new_state_table;
std::map<int, int> old_to_new_state;
for (int i = 0; i < SIZE(fsm_data.state_table); i++)
if (i != fsm_data.reset_state)
unreachable_states.insert(i);
for (auto &trans : fsm_data.transition_table)
unreachable_states.erase(trans.state_out);
if (unreachable_states.empty())
break;
for (int i = 0; i < SIZE(fsm_data.state_table); i++) {
if (unreachable_states.count(i)) {
log(" Removing unreachable state %s.\n", log_signal(fsm_data.state_table[i]));
continue;
}
old_to_new_state[i] = SIZE(new_state_table);
new_state_table.push_back(fsm_data.state_table[i]);
}
for (auto trans : fsm_data.transition_table) {
if (unreachable_states.count(trans.state_in))
continue;
trans.state_in = old_to_new_state.at(trans.state_in);
trans.state_out = old_to_new_state.at(trans.state_out);
new_transition_table.push_back(trans);
}
new_transition_table.swap(fsm_data.transition_table);
new_state_table.swap(fsm_data.state_table);
fsm_data.reset_state = old_to_new_state.at(fsm_data.reset_state);
}
}
bool signal_is_unused(RTLIL::SigSpec sig)
{
RTLIL::SigBit bit = sig.to_single_sigbit();
@ -253,6 +295,8 @@ struct FsmOpt
this->cell = cell;
this->module = module;
opt_unreachable_states();
opt_unused_outputs();
opt_alias_inputs();

View File

@ -17,7 +17,8 @@ python generate.py
idx=$( printf "%05d" $i )
echo "temp/uut_${idx}.log: temp/uut_${idx}.ys temp/uut_${idx}.v"
echo " @echo -n '[$i]'"
echo " @../../yosys -ql temp/uut_${idx}.log temp/uut_${idx}.ys"
echo " @../../yosys -ql temp/uut_${idx}.out temp/uut_${idx}.ys"
echo " @mv temp/uut_${idx}.out temp/uut_${idx}.log"
echo " @grep -q 'SAT proof finished' temp/uut_${idx}.log && echo -n K || echo -n T"
all_targets="$all_targets temp/uut_${idx}.log"
done