yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
FsmOpt Struct Reference
+ Collaboration diagram for FsmOpt:

Public Member Functions

void opt_unreachable_states ()
 
bool signal_is_unused (RTLIL::SigSpec sig)
 
void opt_const_and_unused_inputs ()
 
void opt_unused_outputs ()
 
void opt_alias_inputs ()
 
void opt_feedback_inputs ()
 
void opt_find_dont_care_worker (std::set< RTLIL::Const > &set, int bit, FsmData::transition_t &tr, bool &did_something)
 
void opt_find_dont_care ()
 
 FsmOpt (RTLIL::Cell *cell, RTLIL::Module *module)
 

Data Fields

FsmData fsm_data
 
RTLIL::Cellcell
 
RTLIL::Modulemodule
 

Detailed Description

Definition at line 31 of file fsm_opt.cc.

Constructor & Destructor Documentation

FsmOpt::FsmOpt ( RTLIL::Cell cell,
RTLIL::Module module 
)
inline

Definition at line 293 of file fsm_opt.cc.

294  {
295  log("Optimizing FSM `%s' from module `%s'.\n", cell->name.c_str(), module->name.c_str());
296 
297  fsm_data.copy_from_cell(cell);
298  this->cell = cell;
299  this->module = module;
300 
302 
304 
308 
310 
311  fsm_data.copy_to_cell(cell);
312  }
const char * c_str() const
Definition: rtlil.h:178
RTLIL::IdString name
Definition: rtlil.h:853
void copy_to_cell(RTLIL::Cell *cell)
Definition: fsmdata.h:34
RTLIL::Module * module
Definition: fsm_opt.cc:35
void opt_const_and_unused_inputs()
Definition: fsm_opt.cc:98
void opt_unreachable_states()
Definition: fsm_opt.cc:37
RTLIL::IdString name
Definition: rtlil.h:599
void opt_alias_inputs()
Definition: fsm_opt.cc:158
void opt_feedback_inputs()
Definition: fsm_opt.cc:195
void opt_find_dont_care()
Definition: fsm_opt.cc:261
void opt_unused_outputs()
Definition: fsm_opt.cc:138
void log(const char *format,...)
Definition: log.cc:180
void copy_from_cell(RTLIL::Cell *cell)
Definition: fsmdata.h:79
FsmData fsm_data
Definition: fsm_opt.cc:33
RTLIL::Cell * cell
Definition: fsm_opt.cc:34

+ Here is the call graph for this function:

Member Function Documentation

void FsmOpt::opt_alias_inputs ( )
inline

Definition at line 158 of file fsm_opt.cc.

159  {
160  RTLIL::SigSpec &ctrl_in = cell->connections_["\\CTRL_IN"];
161 
162  for (int i = 0; i < ctrl_in.size(); i++)
163  for (int j = i+1; j < ctrl_in.size(); j++)
164  if (ctrl_in.extract(i, 1) == ctrl_in.extract(j, 1))
165  {
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;
168 
169  for (auto tr : fsm_data.transition_table)
170  {
171  RTLIL::State &si = tr.ctrl_in.bits[i];
172  RTLIL::State &sj = tr.ctrl_in.bits[j];
173 
174  if (si > RTLIL::State::S1)
175  si = sj;
176  else if (sj > RTLIL::State::S1)
177  sj = si;
178 
179  if (si == sj) {
180  RTLIL::SigSpec tmp(tr.ctrl_in);
181  tmp.remove(j, 1);
182  tr.ctrl_in = tmp.as_const();
183  new_transition_table.push_back(tr);
184  }
185  }
186 
187  ctrl_in.remove(j--, 1);
189 
190  fsm_data.transition_table.swap(new_transition_table);
191  new_transition_table.clear();
192  }
193  }
std::vector< transition_t > transition_table
Definition: fsmdata.h:31
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
Definition: log.cc:269
int size() const
Definition: rtlil.h:1019
void remove(const RTLIL::SigSpec &pattern)
Definition: rtlil.cc:2342
int num_inputs
Definition: fsmdata.h:29
void log(const char *format,...)
Definition: log.cc:180
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
Definition: rtlil.cc:2414
State
Definition: rtlil.h:29
std::map< RTLIL::IdString, RTLIL::SigSpec > connections_
Definition: rtlil.h:855
FsmData fsm_data
Definition: fsm_opt.cc:33
RTLIL::Cell * cell
Definition: fsm_opt.cc:34

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void FsmOpt::opt_const_and_unused_inputs ( )
inline

Definition at line 98 of file fsm_opt.cc.

99  {
100  RTLIL::SigSpec ctrl_in = cell->getPort("\\CTRL_IN");
101  std::vector<bool> ctrl_in_used(ctrl_in.size());
102 
103  std::vector<FsmData::transition_t> new_transition_table;
104  for (auto &tr : fsm_data.transition_table) {
105  for (int i = 0; i < ctrl_in.size(); i++) {
106  RTLIL::SigSpec ctrl_bit = ctrl_in.extract(i, 1);
107  if (ctrl_bit.is_fully_const()) {
108  if (tr.ctrl_in.bits[i] <= RTLIL::State::S1 && RTLIL::SigSpec(tr.ctrl_in.bits[i]) != ctrl_bit)
109  goto delete_this_transition;
110  continue;
111  }
112  if (tr.ctrl_in.bits[i] <= RTLIL::State::S1)
113  ctrl_in_used[i] = true;
114  }
115  new_transition_table.push_back(tr);
116  delete_this_transition:;
117  }
118 
119  for (int i = int(ctrl_in_used.size())-1; i >= 0; i--) {
120  if (!ctrl_in_used[i]) {
121  log(" Removing unused input signal %s.\n", log_signal(cell->getPort("\\CTRL_IN").extract(i, 1)));
122  for (auto &tr : new_transition_table) {
123  RTLIL::SigSpec tmp(tr.ctrl_in);
124  tmp.remove(i, 1);
125  tr.ctrl_in = tmp.as_const();
126  }
127  RTLIL::SigSpec new_ctrl_in = cell->getPort("\\CTRL_IN");
128  new_ctrl_in.remove(i, 1);
129  cell->setPort("\\CTRL_IN", new_ctrl_in);
131  }
132  }
133 
134  fsm_data.transition_table.swap(new_transition_table);
135  new_transition_table.clear();
136  }
std::vector< transition_t > transition_table
Definition: fsmdata.h:31
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
Definition: log.cc:269
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
Definition: rtlil.cc:1789
int size() const
Definition: rtlil.h:1019
void remove(const RTLIL::SigSpec &pattern)
Definition: rtlil.cc:2342
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
Definition: rtlil.cc:1809
int num_inputs
Definition: fsmdata.h:29
bool is_fully_const() const
Definition: rtlil.cc:2763
void log(const char *format,...)
Definition: log.cc:180
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
Definition: rtlil.cc:2414
FsmData fsm_data
Definition: fsm_opt.cc:33
RTLIL::Cell * cell
Definition: fsm_opt.cc:34

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void FsmOpt::opt_feedback_inputs ( )
inline

Definition at line 195 of file fsm_opt.cc.

196  {
197  RTLIL::SigSpec &ctrl_in = cell->connections_["\\CTRL_IN"];
198  RTLIL::SigSpec &ctrl_out = cell->connections_["\\CTRL_OUT"];
199 
200  for (int j = 0; j < ctrl_out.size(); j++)
201  for (int i = 0; i < ctrl_in.size(); i++)
202  if (ctrl_in.extract(i, 1) == ctrl_out.extract(j, 1))
203  {
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;
206 
207  for (auto tr : fsm_data.transition_table)
208  {
209  RTLIL::State &si = tr.ctrl_in.bits[i];
210  RTLIL::State &sj = tr.ctrl_out.bits[j];
211 
212  if (si > RTLIL::State::S1 || si == sj) {
213  RTLIL::SigSpec tmp(tr.ctrl_in);
214  tmp.remove(i, 1);
215  tr.ctrl_in = tmp.as_const();
216  new_transition_table.push_back(tr);
217  }
218  }
219 
220  ctrl_in.remove(i--, 1);
222 
223  fsm_data.transition_table.swap(new_transition_table);
224  new_transition_table.clear();
225  }
226  }
std::vector< transition_t > transition_table
Definition: fsmdata.h:31
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
Definition: log.cc:269
int size() const
Definition: rtlil.h:1019
void remove(const RTLIL::SigSpec &pattern)
Definition: rtlil.cc:2342
int num_inputs
Definition: fsmdata.h:29
void log(const char *format,...)
Definition: log.cc:180
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
Definition: rtlil.cc:2414
State
Definition: rtlil.h:29
std::map< RTLIL::IdString, RTLIL::SigSpec > connections_
Definition: rtlil.h:855
FsmData fsm_data
Definition: fsm_opt.cc:33
RTLIL::Cell * cell
Definition: fsm_opt.cc:34

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void FsmOpt::opt_find_dont_care ( )
inline

Definition at line 261 of file fsm_opt.cc.

262  {
263  typedef std::pair<std::pair<int, int>, RTLIL::Const> group_t;
264  std::map<group_t, std::set<RTLIL::Const>> transitions_by_group;
265 
266  for (auto &tr : fsm_data.transition_table) {
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);
269  }
270 
271  fsm_data.transition_table.clear();
272  for (auto &it : transitions_by_group)
273  {
275  tr.state_in = it.first.first.first;
276  tr.state_out = it.first.first.second;
277  tr.ctrl_out = it.first.second;
278 
279  bool did_something = true;
280  while (did_something) {
281  did_something = false;
282  for (int i = 0; i < fsm_data.num_inputs; i++)
283  opt_find_dont_care_worker(it.second, i, tr, did_something);
284  }
285 
286  for (auto &ci : it.second) {
287  tr.ctrl_in = ci;
288  fsm_data.transition_table.push_back(tr);
289  }
290  }
291  }
std::vector< transition_t > transition_table
Definition: fsmdata.h:31
void opt_find_dont_care_worker(std::set< RTLIL::Const > &set, int bit, FsmData::transition_t &tr, bool &did_something)
Definition: fsm_opt.cc:228
RTLIL::Const ctrl_out
Definition: fsmdata.h:30
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool did_something
Definition: opt_const.cc:32
RTLIL::Const ctrl_in
Definition: fsmdata.h:30
int num_inputs
Definition: fsmdata.h:29
FsmData fsm_data
Definition: fsm_opt.cc:33

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void FsmOpt::opt_find_dont_care_worker ( std::set< RTLIL::Const > &  set,
int  bit,
FsmData::transition_t tr,
bool &  did_something 
)
inline

Definition at line 228 of file fsm_opt.cc.

229  {
230  std::set<RTLIL::Const> new_set;
231 
232  for (auto &pattern : set)
233  {
234  if (pattern.bits[bit] > RTLIL::State::S1) {
235  new_set.insert(pattern);
236  continue;
237  }
238 
239  RTLIL::Const other_pattern = pattern;
240 
241  if (pattern.bits[bit] == RTLIL::State::S1)
242  other_pattern.bits[bit] = RTLIL::State::S0;
243  else
244  other_pattern.bits[bit] = RTLIL::State::S1;
245 
246  if (set.count(other_pattern) > 0) {
247  log(" Merging pattern %s and %s from group (%d %d %s).\n", log_signal(pattern), log_signal(other_pattern),
248  tr.state_in, tr.state_out, log_signal(tr.ctrl_out));
249  other_pattern.bits[bit] = RTLIL::State::Sa;
250  new_set.insert(other_pattern);
251  did_something = true;
252  continue;
253  }
254 
255  new_set.insert(pattern);
256  }
257 
258  set.swap(new_set);
259  }
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
Definition: log.cc:269
RTLIL::Const ctrl_out
Definition: fsmdata.h:30
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool did_something
Definition: opt_const.cc:32
void log(const char *format,...)
Definition: log.cc:180
std::vector< RTLIL::State > bits
Definition: rtlil.h:438

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void FsmOpt::opt_unreachable_states ( )
inline

Definition at line 37 of file fsm_opt.cc.

38  {
39  while (1)
40  {
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;
45 
46  for (int i = 0; i < GetSize(fsm_data.state_table); i++)
47  if (i != fsm_data.reset_state)
48  unreachable_states.insert(i);
49 
50  for (auto &trans : fsm_data.transition_table)
51  unreachable_states.erase(trans.state_out);
52 
53  if (unreachable_states.empty())
54  break;
55 
56  for (int i = 0; i < GetSize(fsm_data.state_table); i++) {
57  if (unreachable_states.count(i)) {
58  log(" Removing unreachable state %s.\n", log_signal(fsm_data.state_table[i]));
59  continue;
60  }
61  old_to_new_state[i] = GetSize(new_state_table);
62  new_state_table.push_back(fsm_data.state_table[i]);
63  }
64 
65  for (auto trans : fsm_data.transition_table) {
66  if (unreachable_states.count(trans.state_in))
67  continue;
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);
71  }
72 
73  new_transition_table.swap(fsm_data.transition_table);
74  new_state_table.swap(fsm_data.state_table);
75  fsm_data.reset_state = old_to_new_state.at(fsm_data.reset_state);
76  }
77  }
std::vector< transition_t > transition_table
Definition: fsmdata.h:31
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
Definition: log.cc:269
int GetSize(RTLIL::Wire *wire)
Definition: yosys.cc:334
std::vector< RTLIL::Const > state_table
Definition: fsmdata.h:32
void log(const char *format,...)
Definition: log.cc:180
FsmData fsm_data
Definition: fsm_opt.cc:33
int reset_state
Definition: fsmdata.h:29

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void FsmOpt::opt_unused_outputs ( )
inline

Definition at line 138 of file fsm_opt.cc.

139  {
140  for (int i = 0; i < fsm_data.num_outputs; i++) {
141  RTLIL::SigSpec sig = cell->getPort("\\CTRL_OUT").extract(i, 1);
142  if (signal_is_unused(sig)) {
143  log(" Removing unused output signal %s.\n", log_signal(sig));
144  RTLIL::SigSpec new_ctrl_out = cell->getPort("\\CTRL_OUT");
145  new_ctrl_out.remove(i, 1);
146  cell->setPort("\\CTRL_OUT", new_ctrl_out);
147  for (auto &tr : fsm_data.transition_table) {
148  RTLIL::SigSpec tmp(tr.ctrl_out);
149  tmp.remove(i, 1);
150  tr.ctrl_out = tmp.as_const();
151  }
153  i--;
154  }
155  }
156  }
std::vector< transition_t > transition_table
Definition: fsmdata.h:31
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
Definition: log.cc:269
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
Definition: rtlil.cc:1789
void remove(const RTLIL::SigSpec &pattern)
Definition: rtlil.cc:2342
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
Definition: rtlil.cc:1809
void log(const char *format,...)
Definition: log.cc:180
bool signal_is_unused(RTLIL::SigSpec sig)
Definition: fsm_opt.cc:79
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
Definition: rtlil.cc:2414
int num_outputs
Definition: fsmdata.h:29
FsmData fsm_data
Definition: fsm_opt.cc:33
RTLIL::Cell * cell
Definition: fsm_opt.cc:34

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool FsmOpt::signal_is_unused ( RTLIL::SigSpec  sig)
inline

Definition at line 79 of file fsm_opt.cc.

80  {
81  RTLIL::SigBit bit = sig.to_single_sigbit();
82 
83  if (bit.wire == NULL || bit.wire->attributes.count("\\unused_bits") == 0)
84  return false;
85 
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)) {
89  free(str);
90  return true;
91  }
92  }
93  free(str);
94 
95  return false;
96  }
RTLIL::Wire * wire
Definition: rtlil.h:907
void free(void *)
int offset
Definition: rtlil.h:910
RTLIL::SigBit to_single_sigbit() const
Definition: rtlil.cc:2945
#define NULL

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Field Documentation

RTLIL::Cell* FsmOpt::cell

Definition at line 34 of file fsm_opt.cc.

FsmData FsmOpt::fsm_data

Definition at line 33 of file fsm_opt.cc.

RTLIL::Module* FsmOpt::module

Definition at line 35 of file fsm_opt.cc.


The documentation for this struct was generated from the following file: