35 for (
auto sync : proc->
syncs)
36 for (
auto &action : sync->actions)
37 if (action.first.size() > 0) {
38 lvalue = action.first;
43 for (
auto sync : proc->
syncs) {
45 for (
auto &action : sync->actions)
46 this_lvalue.
append(action.first);
49 if (common_sig.
size() > 0)
62 for (
auto &it : async_rules)
69 for (
auto &it2 : it.second)
71 sync_low_signals.
append(it2->signal);
73 sync_high_signals.
append(it2->signal);
77 if (sync_low_signals.
size() > 1) {
82 cell->
setPort(
"\\A", sync_low_signals);
86 if (sync_low_signals.
size() > 0) {
91 cell->
setPort(
"\\A", sync_low_signals);
96 if (sync_high_signals.
size() > 1) {
101 cell->
setPort(
"\\A", sync_high_signals);
109 inv_cell->
setPort(
"\\A", sync_value);
114 mux_set_cell->
setPort(
"\\A", sig_sr_set);
115 mux_set_cell->
setPort(
"\\B", sync_value);
116 mux_set_cell->
setPort(
"\\S", sync_high_signals);
121 mux_clr_cell->
setPort(
"\\A", sig_sr_clr);
122 mux_clr_cell->
setPort(
"\\B", sync_value_inv);
123 mux_clr_cell->
setPort(
"\\S", sync_high_signals);
127 std::stringstream sstr;
128 sstr <<
"$procdff$" << (
autoidx++);
131 cell->attributes = proc->attributes;
133 cell->parameters[
"\\CLK_POLARITY"] =
RTLIL::Const(clk_polarity, 1);
134 cell->parameters[
"\\SET_POLARITY"] =
RTLIL::Const(
true, 1);
135 cell->parameters[
"\\CLR_POLARITY"] =
RTLIL::Const(
true, 1);
136 cell->setPort(
"\\D", sig_d);
137 cell->setPort(
"\\Q", sig_q);
138 cell->setPort(
"\\CLK", clk);
139 cell->setPort(
"\\SET", sig_sr_set);
140 cell->setPort(
"\\CLR", sig_sr_clr);
142 log(
" created %s cell `%s' with %s edge clock and multiple level-sensitive resets.\n",
143 cell->type.c_str(), cell->name.c_str(), clk_polarity ?
"positive" :
"negative");
149 std::stringstream sstr;
150 sstr <<
"$procdff$" << (
autoidx++);
160 inv_set->
setPort(
"\\A", sig_set);
161 inv_set->
setPort(
"\\Y", sig_set_inv);
166 mux_sr_set->
setPort(set_polarity ?
"\\B" :
"\\A", sig_set);
167 mux_sr_set->
setPort(
"\\Y", sig_sr_set);
168 mux_sr_set->
setPort(
"\\S", set);
173 mux_sr_clr->
setPort(set_polarity ?
"\\B" :
"\\A", sig_set_inv);
174 mux_sr_clr->
setPort(
"\\Y", sig_sr_clr);
175 mux_sr_clr->
setPort(
"\\S", set);
178 cell->attributes = proc->attributes;
186 cell->
setPort(
"\\SET", sig_sr_set);
187 cell->
setPort(
"\\CLR", sig_sr_clr);
189 log(
" created %s cell `%s' with %s edge clock and %s level non-const reset.\n", cell->
type.
c_str(), cell->
name.
c_str(),
190 clk_polarity ?
"positive" :
"negative", set_polarity ?
"positive" :
"negative");
196 std::stringstream sstr;
197 sstr <<
"$procdff$" << (
autoidx++);
200 cell->attributes = proc->attributes;
204 cell->parameters[
"\\ARST_POLARITY"] =
RTLIL::Const(arst_polarity, 1);
205 cell->parameters[
"\\ARST_VALUE"] = val_rst;
207 cell->parameters[
"\\CLK_POLARITY"] =
RTLIL::Const(clk_polarity, 1);
209 cell->setPort(
"\\D", sig_in);
210 cell->setPort(
"\\Q", sig_out);
212 cell->setPort(
"\\ARST", *arst);
213 cell->setPort(
"\\CLK", clk);
215 log(
" created %s cell `%s' with %s edge clock", cell->type.c_str(), cell->name.c_str(), clk_polarity ?
"positive" :
"negative");
217 log(
" and %s level reset", arst_polarity ?
"positive" :
"negative");
226 bool free_sync_level =
false;
231 log(
"Creating register for signal `%s.%s' using process `%s.%s'.\n",
240 std::map<RTLIL::SigSpec, std::set<RTLIL::SyncRule*>> many_async_rules;
242 for (
auto sync : proc->
syncs)
243 for (
auto &action : sync->actions)
245 if (action.first.extract(sig).size() == 0)
249 if (sync_level !=
NULL && sync_level != sync) {
251 many_async_rules[rstval].insert(sync_level);
255 sig.
replace(action.first, action.second, &rstval);
259 if (sync_edge !=
NULL && sync_edge != sync)
260 log_error(
"Multiple edge sensitive events found for this signal!\n");
261 sig.
replace(action.first, action.second, &insig);
265 if (sync_always !=
NULL && sync_always != sync)
266 log_error(
"Multiple always events found for this signal!\n");
267 sig.
replace(action.first, action.second, &insig);
271 log_error(
"Event with any-edge sensitivity found for this signal!\n");
274 action.first.remove2(sig, &action.second);
277 if (many_async_rules.size() > 0)
279 many_async_rules[rstval].insert(sync_level);
280 if (many_async_rules.size() == 1)
286 free_sync_level =
true;
289 for (
auto &it : many_async_rules[rstval]) {
290 inputs.
append(it->signal);
297 cell->parameters[
"\\B_SIGNED"] =
RTLIL::Const(
false, 1);
301 cell->setPort(
"\\A", inputs);
302 cell->setPort(
"\\B", compare);
303 cell->setPort(
"\\Y", sync_level->signal);
305 many_async_rules.clear();
324 if (sync_edge || sync_level || many_async_rules.size() > 0)
325 log_error(
"Mixed always event with edge and/or level sensitive events!\n");
326 log(
" created direct connection (no actual register cell created).\n");
332 log_error(
"Missing edge-sensitive event for this signal!\n");
334 if (many_async_rules.size() > 0)
339 else if (!rstval.is_fully_const() && !ce.
eval(rstval))
345 sync_edge->
signal, sync_level->signal, proc);
348 gen_dff(mod, insig, rstval.as_const(), sig,
351 sync_edge->
signal, sync_level ? &sync_level->signal :
NULL, proc);
364 log(
" proc_dff [selection]\n");
366 log(
"This pass identifies flip-flops in the processes and converts them to\n");
367 log(
"d-type flip-flop cells.\n");
372 log_header(
"Executing PROC_DFF pass (convert process syncs to FFs).\n");
376 for (
auto mod : design->
modules())
379 for (
auto &proc_it : mod->processes)
380 if (design->
selected(mod, proc_it.second))
const char * c_str() const
bool selected(T1 *module) const
void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_out, bool clk_polarity, bool set_polarity, RTLIL::SigSpec clk, RTLIL::SigSpec set, RTLIL::Process *proc)
void log_warning(const char *format,...)
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
void log_header(const char *format,...)
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
bool eval(RTLIL::Cell *cell, RTLIL::SigSpec &undef)
void log_error(const char *format,...)
std::map< RTLIL::IdString, RTLIL::Const > parameters
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN RTLIL::SigSpec find_any_lvalue(const RTLIL::Process *proc)
void apply(RTLIL::SigBit &bit) const
void connect(const RTLIL::SigSig &conn)
#define PRIVATE_NAMESPACE_BEGIN
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
#define log_assert(_assert_expr_)
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
#define PRIVATE_NAMESPACE_END
void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce)
#define USING_YOSYS_NAMESPACE
RTLIL::ObjRange< RTLIL::Module * > modules()
void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
void gen_dff(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::Const val_rst, RTLIL::SigSpec sig_out, bool clk_polarity, bool arst_polarity, RTLIL::SigSpec clk, RTLIL::SigSpec *arst, RTLIL::Process *proc)
void log(const char *format,...)
std::vector< RTLIL::SyncRule * > syncs
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
void append(const RTLIL::SigSpec &signal)
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
std::pair< SigSpec, SigSpec > SigSig
YOSYS_NAMESPACE_BEGIN int autoidx
void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, RTLIL::SigSpec clk, bool clk_polarity, std::map< RTLIL::SigSpec, std::set< RTLIL::SyncRule * >> &async_rules, RTLIL::Process *proc)