41 std::set<int> unreachable_states;
42 std::vector<FsmData::transition_t> new_transition_table;
43 std::vector<RTLIL::Const> new_state_table;
44 std::map<int, int> old_to_new_state;
48 unreachable_states.insert(i);
51 unreachable_states.erase(trans.state_out);
53 if (unreachable_states.empty())
57 if (unreachable_states.count(i)) {
61 old_to_new_state[i] =
GetSize(new_state_table);
66 if (unreachable_states.count(trans.state_in))
68 trans.state_in = old_to_new_state.at(trans.state_in);
69 trans.state_out = old_to_new_state.at(trans.state_out);
70 new_transition_table.push_back(trans);
83 if (bit.
wire ==
NULL || bit.
wire->attributes.count(
"\\unused_bits") == 0)
86 char *str = strdup(bit.
wire->attributes[
"\\unused_bits"].decode_string().c_str());
87 for (
char *tok = strtok(str,
" "); tok !=
NULL; tok = strtok(
NULL,
" ")) {
88 if (tok[0] && bit.
offset == atoi(tok)) {
101 std::vector<bool> ctrl_in_used(ctrl_in.
size());
103 std::vector<FsmData::transition_t> new_transition_table;
105 for (
int i = 0; i < ctrl_in.
size(); i++) {
109 goto delete_this_transition;
113 ctrl_in_used[i] =
true;
115 new_transition_table.push_back(tr);
116 delete_this_transition:;
119 for (
int i =
int(ctrl_in_used.size())-1; i >= 0; i--) {
120 if (!ctrl_in_used[i]) {
122 for (
auto &tr : new_transition_table) {
135 new_transition_table.clear();
143 log(
" Removing unused output signal %s.\n",
log_signal(sig));
145 new_ctrl_out.
remove(i, 1);
162 for (
int i = 0; i < ctrl_in.
size(); i++)
163 for (
int j = i+1; j < ctrl_in.
size(); j++)
166 log(
" Optimize handling of signal %s that is connected to inputs %d and %d.\n",
log_signal(ctrl_in.
extract(i, 1)), i, j);
167 std::vector<FsmData::transition_t> new_transition_table;
183 new_transition_table.push_back(tr);
191 new_transition_table.clear();
200 for (
int j = 0; j < ctrl_out.
size(); j++)
201 for (
int i = 0; i < ctrl_in.
size(); i++)
204 log(
" Optimize handling of signal %s that is connected to input %d and output %d.\n",
log_signal(ctrl_in.
extract(i, 1)), i, j);
205 std::vector<FsmData::transition_t> new_transition_table;
216 new_transition_table.push_back(tr);
224 new_transition_table.clear();
230 std::set<RTLIL::Const> new_set;
232 for (
auto &pattern : set)
235 new_set.insert(pattern);
246 if (set.count(other_pattern) > 0) {
250 new_set.insert(other_pattern);
251 did_something =
true;
255 new_set.insert(pattern);
263 typedef std::pair<std::pair<int, int>,
RTLIL::Const> group_t;
264 std::map<group_t, std::set<RTLIL::Const>> transitions_by_group;
267 group_t group(std::pair<int, int>(tr.state_in, tr.state_out), tr.ctrl_out);
268 transitions_by_group[group].insert(tr.ctrl_in);
272 for (
auto &it : transitions_by_group)
280 while (did_something) {
281 did_something =
false;
286 for (
auto &ci : it.second) {
319 FsmOpt fsmopt(cell, module);
330 log(
" fsm_opt [selection]\n");
332 log(
"This pass optimizes FSM cells. It detects which output signals are actually\n");
333 log(
"not used and removes them from the FSM. This pass is usually used in\n");
334 log(
"combination with the 'opt_clean' pass (see also 'help fsm').\n");
339 log_header(
"Executing FSM_OPT pass (simple optimizations of FSMs).\n");
342 for (
auto &mod_it : design->
modules_) {
343 if (design->
selected(mod_it.second))
344 for (
auto &cell_it : mod_it.second->cells_)
345 if (cell_it.second->type ==
"$fsm" && design->
selected(mod_it.second, cell_it.second))
const char * c_str() const
bool selected(T1 *module) const
std::vector< transition_t > transition_table
void opt_find_dont_care_worker(std::set< RTLIL::Const > &set, int bit, FsmData::transition_t &tr, bool &did_something)
void log_header(const char *format,...)
#define YOSYS_NAMESPACE_PREFIX
RTLIL::Const as_const() const
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
void copy_to_cell(RTLIL::Cell *cell)
void opt_const_and_unused_inputs()
void remove(const RTLIL::SigSpec &pattern)
FsmOpt(RTLIL::Cell *cell, RTLIL::Module *module)
void opt_unreachable_states()
static void optimize_fsm(RTLIL::Cell *cell, RTLIL::Module *module)
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool did_something
#define PRIVATE_NAMESPACE_BEGIN
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
int GetSize(RTLIL::Wire *wire)
bool is_fully_const() const
#define PRIVATE_NAMESPACE_END
RTLIL::SigBit to_single_sigbit() const
void opt_feedback_inputs()
#define USING_YOSYS_NAMESPACE
std::map< RTLIL::IdString, RTLIL::Module * > modules_
std::vector< RTLIL::Const > state_table
void opt_find_dont_care()
void opt_unused_outputs()
void log(const char *format,...)
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
void copy_from_cell(RTLIL::Cell *cell)
bool signal_is_unused(RTLIL::SigSpec sig)
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
std::vector< RTLIL::State > bits
std::map< RTLIL::IdString, RTLIL::SigSpec > connections_
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)