yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
proc_arst.cc File Reference
#include "kernel/register.h"
#include "kernel/sigtools.h"
#include "kernel/log.h"
#include <stdlib.h>
#include <stdio.h>
+ Include dependency graph for proc_arst.cc:

Go to the source code of this file.

Data Structures

struct  ProcArstPass
 

Functions

YOSYS_NAMESPACE_BEGIN void proc_clean_case (RTLIL::CaseRule *cs, bool &did_something, int &count, int max_depth)
 
YOSYS_NAMESPACE_END
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN bool 
check_signal (RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref, bool &polarity)
 
void apply_const (RTLIL::Module *mod, const RTLIL::SigSpec rspec, RTLIL::SigSpec &rval, RTLIL::CaseRule *cs, RTLIL::SigSpec const_sig, bool polarity, bool unknown)
 
void eliminate_const (RTLIL::Module *mod, RTLIL::CaseRule *cs, RTLIL::SigSpec const_sig, bool polarity)
 
void proc_arst (RTLIL::Module *mod, RTLIL::Process *proc, SigMap &assign_map)
 

Variables

ProcArstPass ProcArstPass
 

Function Documentation

void apply_const ( RTLIL::Module mod,
const RTLIL::SigSpec  rspec,
RTLIL::SigSpec rval,
RTLIL::CaseRule cs,
RTLIL::SigSpec  const_sig,
bool  polarity,
bool  unknown 
)

Definition at line 88 of file proc_arst.cc.

89 {
90  for (auto &action : cs->actions) {
91  if (unknown)
92  rspec.replace(action.first, RTLIL::SigSpec(RTLIL::State::Sm, action.second.size()), &rval);
93  else
94  rspec.replace(action.first, action.second, &rval);
95  }
96 
97  for (auto sw : cs->switches) {
98  if (sw->signal.size() == 0) {
99  for (auto cs2 : sw->cases)
100  apply_const(mod, rspec, rval, cs2, const_sig, polarity, unknown);
101  }
102  bool this_polarity = polarity;
103  if (check_signal(mod, sw->signal, const_sig, this_polarity)) {
104  for (auto cs2 : sw->cases) {
105  for (auto comp : cs2->compare)
106  if (comp == RTLIL::SigSpec(this_polarity, 1))
107  goto matched_case;
108  if (cs2->compare.size() == 0) {
109  matched_case:
110  apply_const(mod, rspec, rval, cs2, const_sig, polarity, false);
111  break;
112  }
113  }
114  } else {
115  for (auto cs2 : sw->cases)
116  apply_const(mod, rspec, rval, cs2, const_sig, polarity, true);
117  }
118  }
119 }
YOSYS_NAMESPACE_END USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref, bool &polarity)
Definition: proc_arst.cc:33
void apply_const(RTLIL::Module *mod, const RTLIL::SigSpec rspec, RTLIL::SigSpec &rval, RTLIL::CaseRule *cs, RTLIL::SigSpec const_sig, bool polarity, bool unknown)
Definition: proc_arst.cc:88
void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
Definition: rtlil.cc:2297
std::vector< RTLIL::SigSig > actions
Definition: rtlil.h:1120
std::vector< RTLIL::SwitchRule * > switches
Definition: rtlil.h:1121

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

YOSYS_NAMESPACE_END USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool check_signal ( RTLIL::Module mod,
RTLIL::SigSpec  signal,
RTLIL::SigSpec  ref,
bool &  polarity 
)

Definition at line 33 of file proc_arst.cc.

34 {
35  if (signal.size() != 1)
36  return false;
37  if (signal == ref)
38  return true;
39 
40  for (auto cell : mod->cells())
41  {
42  if (cell->type == "$reduce_or" && cell->getPort("\\Y") == signal)
43  return check_signal(mod, cell->getPort("\\A"), ref, polarity);
44 
45  if (cell->type == "$reduce_bool" && cell->getPort("\\Y") == signal)
46  return check_signal(mod, cell->getPort("\\A"), ref, polarity);
47 
48  if (cell->type == "$logic_not" && cell->getPort("\\Y") == signal) {
49  polarity = !polarity;
50  return check_signal(mod, cell->getPort("\\A"), ref, polarity);
51  }
52 
53  if (cell->type == "$not" && cell->getPort("\\Y") == signal) {
54  polarity = !polarity;
55  return check_signal(mod, cell->getPort("\\A"), ref, polarity);
56  }
57 
58  if ((cell->type == "$eq" || cell->type == "$eqx") && cell->getPort("\\Y") == signal) {
59  if (cell->getPort("\\A").is_fully_const()) {
60  if (!cell->getPort("\\A").as_bool())
61  polarity = !polarity;
62  return check_signal(mod, cell->getPort("\\B"), ref, polarity);
63  }
64  if (cell->getPort("\\B").is_fully_const()) {
65  if (!cell->getPort("\\B").as_bool())
66  polarity = !polarity;
67  return check_signal(mod, cell->getPort("\\A"), ref, polarity);
68  }
69  }
70 
71  if ((cell->type == "$ne" || cell->type == "$nex") && cell->getPort("\\Y") == signal) {
72  if (cell->getPort("\\A").is_fully_const()) {
73  if (cell->getPort("\\A").as_bool())
74  polarity = !polarity;
75  return check_signal(mod, cell->getPort("\\B"), ref, polarity);
76  }
77  if (cell->getPort("\\B").is_fully_const()) {
78  if (cell->getPort("\\B").as_bool())
79  polarity = !polarity;
80  return check_signal(mod, cell->getPort("\\A"), ref, polarity);
81  }
82  }
83  }
84 
85  return false;
86 }
YOSYS_NAMESPACE_END USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref, bool &polarity)
Definition: proc_arst.cc:33
int size() const
Definition: rtlil.h:1019
RTLIL::ObjRange< RTLIL::Cell * > cells()
Definition: rtlil.h:641

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void eliminate_const ( RTLIL::Module mod,
RTLIL::CaseRule cs,
RTLIL::SigSpec  const_sig,
bool  polarity 
)

Definition at line 121 of file proc_arst.cc.

122 {
123  for (auto sw : cs->switches) {
124  bool this_polarity = polarity;
125  if (check_signal(mod, sw->signal, const_sig, this_polarity)) {
126  bool found_rem_path = false;
127  for (size_t i = 0; i < sw->cases.size(); i++) {
128  RTLIL::CaseRule *cs2 = sw->cases[i];
129  for (auto comp : cs2->compare)
130  if (comp == RTLIL::SigSpec(this_polarity, 1))
131  goto matched_case;
132  if (found_rem_path) {
133  matched_case:
134  sw->cases.erase(sw->cases.begin() + (i--));
135  delete cs2;
136  continue;
137  }
138  found_rem_path = true;
139  cs2->compare.clear();
140  }
141  sw->signal = RTLIL::SigSpec();
142  } else {
143  for (auto cs2 : sw->cases)
144  eliminate_const(mod, cs2, const_sig, polarity);
145  }
146  }
147 
148  int dummy_count = 0;
149  bool did_something = true;
150  while (did_something) {
151  did_something = false;
152  proc_clean_case(cs, did_something, dummy_count, 1);
153  }
154 }
YOSYS_NAMESPACE_END USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref, bool &polarity)
Definition: proc_arst.cc:33
std::vector< RTLIL::SigSpec > compare
Definition: rtlil.h:1119
void eliminate_const(RTLIL::Module *mod, RTLIL::CaseRule *cs, RTLIL::SigSpec const_sig, bool polarity)
Definition: proc_arst.cc:121
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool did_something
Definition: opt_const.cc:32
YOSYS_NAMESPACE_BEGIN void proc_clean_case(RTLIL::CaseRule *cs, bool &did_something, int &count, int max_depth)
Definition: proc_clean.cc:99
std::vector< RTLIL::SwitchRule * > switches
Definition: rtlil.h:1121

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void proc_arst ( RTLIL::Module mod,
RTLIL::Process proc,
SigMap assign_map 
)

Definition at line 156 of file proc_arst.cc.

157 {
158 restart_proc_arst:
159  if (proc->root_case.switches.size() != 1)
160  return;
161 
162  RTLIL::SigSpec root_sig = proc->root_case.switches[0]->signal;
163 
164  for (auto &sync : proc->syncs) {
165  if (sync->type == RTLIL::SyncType::STp || sync->type == RTLIL::SyncType::STn) {
166  bool polarity = sync->type == RTLIL::SyncType::STp;
167  if (check_signal(mod, root_sig, sync->signal, polarity)) {
168  if (proc->syncs.size() == 1) {
169  log("Found VHDL-style edge-trigger %s in `%s.%s'.\n", log_signal(sync->signal), mod->name.c_str(), proc->name.c_str());
170  } else {
171  log("Found async reset %s in `%s.%s'.\n", log_signal(sync->signal), mod->name.c_str(), proc->name.c_str());
172  sync->type = sync->type == RTLIL::SyncType::STp ? RTLIL::SyncType::ST1 : RTLIL::SyncType::ST0;
173  }
174  for (auto &action : sync->actions) {
175  RTLIL::SigSpec rspec = action.second;
177  for (int i = 0; i < GetSize(rspec); i++)
178  if (rspec[i].wire == NULL)
179  rval[i] = rspec[i];
180  RTLIL::SigSpec last_rval;
181  for (int count = 0; rval != last_rval; count++) {
182  last_rval = rval;
183  apply_const(mod, rspec, rval, &proc->root_case, root_sig, polarity, false);
184  assign_map.apply(rval);
185  if (rval.is_fully_const())
186  break;
187  if (count > 100)
188  log_error("Async reset %s yields endless loop at value %s for signal %s.\n",
189  log_signal(sync->signal), log_signal(rval), log_signal(action.first));
190  rspec = rval;
191  }
192  if (rval.has_marked_bits())
193  log_error("Async reset %s yields non-constant value %s for signal %s.\n",
194  log_signal(sync->signal), log_signal(rval), log_signal(action.first));
195  action.second = rval;
196  }
197  eliminate_const(mod, &proc->root_case, root_sig, polarity);
198  goto restart_proc_arst;
199  }
200  }
201  }
202 }
const char * c_str() const
Definition: rtlil.h:178
YOSYS_NAMESPACE_END USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref, bool &polarity)
Definition: proc_arst.cc:33
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
Definition: log.cc:269
void log_error(const char *format,...)
Definition: log.cc:204
int size() const
Definition: rtlil.h:1019
void apply(RTLIL::SigBit &bit) const
Definition: sigtools.h:383
void eliminate_const(RTLIL::Module *mod, RTLIL::CaseRule *cs, RTLIL::SigSpec const_sig, bool polarity)
Definition: proc_arst.cc:121
void apply_const(RTLIL::Module *mod, const RTLIL::SigSpec rspec, RTLIL::SigSpec &rval, RTLIL::CaseRule *cs, RTLIL::SigSpec const_sig, bool polarity, bool unknown)
Definition: proc_arst.cc:88
int GetSize(RTLIL::Wire *wire)
Definition: yosys.cc:334
bool is_fully_const() const
Definition: rtlil.cc:2763
RTLIL::IdString name
Definition: rtlil.h:599
RTLIL::IdString name
Definition: rtlil.h:1154
#define NULL
void log(const char *format,...)
Definition: log.cc:180
std::vector< RTLIL::SyncRule * > syncs
Definition: rtlil.h:1157
std::vector< RTLIL::SwitchRule * > switches
Definition: rtlil.h:1121
bool has_marked_bits() const
Definition: rtlil.cc:2804
RTLIL_ATTRIBUTE_MEMBERS RTLIL::CaseRule root_case
Definition: rtlil.h:1156

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

PRIVATE_NAMESPACE_END YOSYS_NAMESPACE_BEGIN void proc_clean_case ( RTLIL::CaseRule cs,
bool &  did_something,
int &  count,
int  max_depth 
)

Definition at line 99 of file proc_clean.cc.

100 {
101  for (size_t i = 0; i < cs->actions.size(); i++) {
102  if (cs->actions[i].first.size() == 0) {
103  did_something = true;
104  cs->actions.erase(cs->actions.begin() + (i--));
105  }
106  }
107  for (size_t i = 0; i < cs->switches.size(); i++) {
108  RTLIL::SwitchRule *sw = cs->switches[i];
109  if (sw->cases.size() == 0) {
110  cs->switches.erase(cs->switches.begin() + (i--));
111  did_something = true;
112  delete sw;
113  count++;
114  } else if (max_depth != 0)
115  proc_clean_switch(sw, cs, did_something, count, max_depth-1);
116  }
117 }
YOSYS_NAMESPACE_END USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did_something, int &count, int max_depth)
Definition: proc_clean.cc:32
RTLIL_ATTRIBUTE_MEMBERS std::vector< RTLIL::CaseRule * > cases
Definition: rtlil.h:1134
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool did_something
Definition: opt_const.cc:32
std::vector< RTLIL::SigSig > actions
Definition: rtlil.h:1120
std::vector< RTLIL::SwitchRule * > switches
Definition: rtlil.h:1121

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation