35 if (signal.
size() != 1)
40 for (
auto cell : mod->
cells())
42 if (cell->type ==
"$reduce_or" && cell->getPort(
"\\Y") == signal)
43 return check_signal(mod, cell->getPort(
"\\A"), ref, polarity);
45 if (cell->type ==
"$reduce_bool" && cell->getPort(
"\\Y") == signal)
46 return check_signal(mod, cell->getPort(
"\\A"), ref, polarity);
48 if (cell->type ==
"$logic_not" && cell->getPort(
"\\Y") == signal) {
50 return check_signal(mod, cell->getPort(
"\\A"), ref, polarity);
53 if (cell->type ==
"$not" && cell->getPort(
"\\Y") == signal) {
55 return check_signal(mod, cell->getPort(
"\\A"), ref, polarity);
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())
62 return check_signal(mod, cell->getPort(
"\\B"), ref, polarity);
64 if (cell->getPort(
"\\B").is_fully_const()) {
65 if (!cell->getPort(
"\\B").as_bool())
67 return check_signal(mod, cell->getPort(
"\\A"), ref, polarity);
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())
75 return check_signal(mod, cell->getPort(
"\\B"), ref, polarity);
77 if (cell->getPort(
"\\B").is_fully_const()) {
78 if (cell->getPort(
"\\B").as_bool())
80 return check_signal(mod, cell->getPort(
"\\A"), ref, polarity);
90 for (
auto &action : cs->
actions) {
94 rspec.
replace(action.first, action.second, &rval);
98 if (sw->signal.size() == 0) {
99 for (
auto cs2 : sw->cases)
100 apply_const(mod, rspec, rval, cs2, const_sig, polarity, unknown);
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)
108 if (cs2->compare.size() == 0) {
110 apply_const(mod, rspec, rval, cs2, const_sig, polarity,
false);
115 for (
auto cs2 : sw->cases)
116 apply_const(mod, rspec, rval, cs2, const_sig, polarity,
true);
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++) {
132 if (found_rem_path) {
134 sw->cases.erase(sw->cases.begin() + (i--));
138 found_rem_path =
true;
143 for (
auto cs2 : sw->cases)
150 while (did_something) {
151 did_something =
false;
164 for (
auto &sync : proc->
syncs) {
167 if (
check_signal(mod, root_sig, sync->signal, polarity)) {
168 if (proc->
syncs.size() == 1) {
174 for (
auto &action : sync->actions) {
177 for (
int i = 0; i <
GetSize(rspec); i++)
178 if (rspec[i].wire ==
NULL)
181 for (
int count = 0; rval != last_rval; count++) {
184 assign_map.
apply(rval);
188 log_error(
"Async reset %s yields endless loop at value %s for signal %s.\n",
193 log_error(
"Async reset %s yields non-constant value %s for signal %s.\n",
195 action.second = rval;
198 goto restart_proc_arst;
210 log(
" proc_arst [-global_arst [!]<netname>] [selection]\n");
212 log(
"This pass identifies asynchronous resets in the processes and converts them\n");
213 log(
"to a different internal representation that is suitable for generating\n");
214 log(
"flip-flop cells with asynchronous resets.\n");
216 log(
" -global_arst [!]<netname>\n");
217 log(
" In modules that have a net with the given name, use this net as async\n");
218 log(
" reset for registers that have been assign initial values in their\n");
219 log(
" declaration ('reg foobar = constant_value;'). Use the '!' modifier for\n");
220 log(
" active low reset signals. Note: the frontend stores the default value\n");
221 log(
" in the 'init' attribute on the net.\n");
226 std::string global_arst;
227 bool global_arst_neg =
false;
229 log_header(
"Executing PROC_ARST pass (detect async resets in processes).\n");
232 for (argidx = 1; argidx < args.size(); argidx++)
234 if (args[argidx] ==
"-global_arst" && argidx+1 < args.size()) {
235 global_arst = args[++argidx];
236 if (!global_arst.empty() && global_arst[0] ==
'!') {
237 global_arst_neg =
true;
238 global_arst = global_arst.substr(1);
248 for (
auto mod : design->
modules())
251 for (
auto &proc_it : mod->processes) {
252 if (!design->
selected(mod, proc_it.second))
254 proc_arst(mod, proc_it.second, assign_map);
255 if (global_arst.empty() || mod->wire(global_arst) ==
nullptr)
257 std::vector<RTLIL::SigSig> arst_actions;
258 for (
auto sync : proc_it.second->syncs)
260 for (
auto &act : sync->actions) {
262 for (
auto &chunk : act.first.chunks())
263 if (chunk.wire && chunk.wire->attributes.count(
"\\init")) {
265 value.
extend(chunk.wire->width,
false);
269 if (arst_sig.
size()) {
270 log(
"Added global reset to process %s: %s <- %s\n",
275 if (!arst_actions.empty()) {
278 sync->
signal = mod->wire(global_arst);
280 proc_it.second->syncs.push_back(sync);
const char * c_str() const
bool selected(T1 *module) const
void log_header(const char *format,...)
#define YOSYS_NAMESPACE_END
YOSYS_NAMESPACE_END USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref, bool &polarity)
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
void log_error(const char *format,...)
std::vector< RTLIL::SigSpec > compare
void apply(RTLIL::SigBit &bit) const
static std::string escape_id(std::string str)
void eliminate_const(RTLIL::Module *mod, RTLIL::CaseRule *cs, RTLIL::SigSpec const_sig, bool polarity)
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool did_something
void proc_arst(RTLIL::Module *mod, RTLIL::Process *proc, SigMap &assign_map)
void apply_const(RTLIL::Module *mod, const RTLIL::SigSpec rspec, RTLIL::SigSpec &rval, RTLIL::CaseRule *cs, RTLIL::SigSpec const_sig, bool polarity, bool unknown)
ProcArstPass ProcArstPass
#define PRIVATE_NAMESPACE_BEGIN
int GetSize(RTLIL::Wire *wire)
bool is_fully_const() const
YOSYS_NAMESPACE_BEGIN void proc_clean_case(RTLIL::CaseRule *cs, bool &did_something, int &count, int max_depth)
#define PRIVATE_NAMESPACE_END
std::vector< RTLIL::SigSig > actions
#define USING_YOSYS_NAMESPACE
RTLIL::ObjRange< RTLIL::Cell * > cells()
RTLIL::ObjRange< RTLIL::Module * > modules()
void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
#define YOSYS_NAMESPACE_BEGIN
void log(const char *format,...)
std::vector< RTLIL::SyncRule * > syncs
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
void append(const RTLIL::SigSpec &signal)
void extend(int width, bool is_signed=false)
std::vector< RTLIL::SigSig > actions
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
std::vector< RTLIL::SwitchRule * > switches
std::pair< SigSpec, SigSpec > SigSig
bool has_marked_bits() const
RTLIL_ATTRIBUTE_MEMBERS RTLIL::CaseRule root_case