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

Go to the source code of this file.

Data Structures

struct  ProcDffPass
 

Functions

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
RTLIL::SigSpec 
find_any_lvalue (const RTLIL::Process *proc)
 
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)
 
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 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 proc_dff (RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce)
 

Variables

ProcDffPass ProcDffPass
 

Function Documentation

Definition at line 31 of file proc_dff.cc.

32 {
33  RTLIL::SigSpec lvalue;
34 
35  for (auto sync : proc->syncs)
36  for (auto &action : sync->actions)
37  if (action.first.size() > 0) {
38  lvalue = action.first;
39  lvalue.sort_and_unify();
40  break;
41  }
42 
43  for (auto sync : proc->syncs) {
44  RTLIL::SigSpec this_lvalue;
45  for (auto &action : sync->actions)
46  this_lvalue.append(action.first);
47  this_lvalue.sort_and_unify();
48  RTLIL::SigSpec common_sig = this_lvalue.extract(lvalue);
49  if (common_sig.size() > 0)
50  lvalue = common_sig;
51  }
52 
53  return lvalue;
54 }
int size() const
Definition: rtlil.h:1019
void sort_and_unify()
Definition: rtlil.cc:2291
std::vector< RTLIL::SyncRule * > syncs
Definition: rtlil.h:1157
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
Definition: rtlil.cc:2414
void append(const RTLIL::SigSpec &signal)
Definition: rtlil.cc:2523

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 
)

Definition at line 193 of file proc_dff.cc.

195 {
196  std::stringstream sstr;
197  sstr << "$procdff$" << (autoidx++);
198 
199  RTLIL::Cell *cell = mod->addCell(sstr.str(), arst ? "$adff" : "$dff");
200  cell->attributes = proc->attributes;
201 
202  cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size());
203  if (arst) {
204  cell->parameters["\\ARST_POLARITY"] = RTLIL::Const(arst_polarity, 1);
205  cell->parameters["\\ARST_VALUE"] = val_rst;
206  }
207  cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1);
208 
209  cell->setPort("\\D", sig_in);
210  cell->setPort("\\Q", sig_out);
211  if (arst)
212  cell->setPort("\\ARST", *arst);
213  cell->setPort("\\CLK", clk);
214 
215  log(" created %s cell `%s' with %s edge clock", cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative");
216  if (arst)
217  log(" and %s level reset", arst_polarity ? "positive" : "negative");
218  log(".\n");
219 }
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
Definition: rtlil.cc:1353
bool clk_polarity
Definition: abc.cc:98
int size() const
Definition: rtlil.h:1019
void log(const char *format,...)
Definition: log.cc:180
YOSYS_NAMESPACE_BEGIN int autoidx
Definition: yosys.cc:51

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 
)

Definition at line 146 of file proc_dff.cc.

148 {
149  std::stringstream sstr;
150  sstr << "$procdff$" << (autoidx++);
151 
152  RTLIL::SigSpec sig_set_inv = mod->addWire(NEW_ID, sig_in.size());
153  RTLIL::SigSpec sig_sr_set = mod->addWire(NEW_ID, sig_in.size());
154  RTLIL::SigSpec sig_sr_clr = mod->addWire(NEW_ID, sig_in.size());
155 
156  RTLIL::Cell *inv_set = mod->addCell(NEW_ID, "$not");
157  inv_set->parameters["\\A_SIGNED"] = RTLIL::Const(0);
158  inv_set->parameters["\\A_WIDTH"] = RTLIL::Const(sig_in.size());
159  inv_set->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_in.size());
160  inv_set->setPort("\\A", sig_set);
161  inv_set->setPort("\\Y", sig_set_inv);
162 
163  RTLIL::Cell *mux_sr_set = mod->addCell(NEW_ID, "$mux");
164  mux_sr_set->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size());
165  mux_sr_set->setPort(set_polarity ? "\\A" : "\\B", RTLIL::Const(0, sig_in.size()));
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);
169 
170  RTLIL::Cell *mux_sr_clr = mod->addCell(NEW_ID, "$mux");
171  mux_sr_clr->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size());
172  mux_sr_clr->setPort(set_polarity ? "\\A" : "\\B", RTLIL::Const(0, sig_in.size()));
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);
176 
177  RTLIL::Cell *cell = mod->addCell(sstr.str(), "$dffsr");
178  cell->attributes = proc->attributes;
179  cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size());
180  cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1);
181  cell->parameters["\\SET_POLARITY"] = RTLIL::Const(true, 1);
182  cell->parameters["\\CLR_POLARITY"] = RTLIL::Const(true, 1);
183  cell->setPort("\\D", sig_in);
184  cell->setPort("\\Q", sig_out);
185  cell->setPort("\\CLK", clk);
186  cell->setPort("\\SET", sig_sr_set);
187  cell->setPort("\\CLR", sig_sr_clr);
188 
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");
191 }
const char * c_str() const
Definition: rtlil.h:178
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
Definition: rtlil.cc:1353
bool clk_polarity
Definition: abc.cc:98
RTLIL::IdString name
Definition: rtlil.h:853
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
Definition: rtlil.cc:1789
RTLIL::IdString type
Definition: rtlil.h:854
std::map< RTLIL::IdString, RTLIL::Const > parameters
Definition: rtlil.h:856
int size() const
Definition: rtlil.h:1019
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
Definition: rtlil.cc:1331
#define NEW_ID
Definition: yosys.h:166
void log(const char *format,...)
Definition: log.cc:180
YOSYS_NAMESPACE_BEGIN int autoidx
Definition: yosys.cc:51

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 
)

Definition at line 56 of file proc_dff.cc.

58 {
59  RTLIL::SigSpec sig_sr_set = RTLIL::SigSpec(0, sig_d.size());
60  RTLIL::SigSpec sig_sr_clr = RTLIL::SigSpec(0, sig_d.size());
61 
62  for (auto &it : async_rules)
63  {
64  RTLIL::SigSpec sync_value = it.first;
65  RTLIL::SigSpec sync_value_inv;
66  RTLIL::SigSpec sync_high_signals;
67  RTLIL::SigSpec sync_low_signals;
68 
69  for (auto &it2 : it.second)
70  if (it2->type == RTLIL::SyncType::ST0)
71  sync_low_signals.append(it2->signal);
72  else if (it2->type == RTLIL::SyncType::ST1)
73  sync_high_signals.append(it2->signal);
74  else
75  log_abort();
76 
77  if (sync_low_signals.size() > 1) {
78  RTLIL::Cell *cell = mod->addCell(NEW_ID, "$reduce_or");
79  cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
80  cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size());
81  cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
82  cell->setPort("\\A", sync_low_signals);
83  cell->setPort("\\Y", sync_low_signals = mod->addWire(NEW_ID));
84  }
85 
86  if (sync_low_signals.size() > 0) {
87  RTLIL::Cell *cell = mod->addCell(NEW_ID, "$not");
88  cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
89  cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size());
90  cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
91  cell->setPort("\\A", sync_low_signals);
92  cell->setPort("\\Y", mod->addWire(NEW_ID));
93  sync_high_signals.append(cell->getPort("\\Y"));
94  }
95 
96  if (sync_high_signals.size() > 1) {
97  RTLIL::Cell *cell = mod->addCell(NEW_ID, "$reduce_or");
98  cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
99  cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_high_signals.size());
100  cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
101  cell->setPort("\\A", sync_high_signals);
102  cell->setPort("\\Y", sync_high_signals = mod->addWire(NEW_ID));
103  }
104 
105  RTLIL::Cell *inv_cell = mod->addCell(NEW_ID, "$not");
106  inv_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
107  inv_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_d.size());
108  inv_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_d.size());
109  inv_cell->setPort("\\A", sync_value);
110  inv_cell->setPort("\\Y", sync_value_inv = mod->addWire(NEW_ID, sig_d.size()));
111 
112  RTLIL::Cell *mux_set_cell = mod->addCell(NEW_ID, "$mux");
113  mux_set_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size());
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);
117  mux_set_cell->setPort("\\Y", sig_sr_set = mod->addWire(NEW_ID, sig_d.size()));
118 
119  RTLIL::Cell *mux_clr_cell = mod->addCell(NEW_ID, "$mux");
120  mux_clr_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size());
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);
124  mux_clr_cell->setPort("\\Y", sig_sr_clr = mod->addWire(NEW_ID, sig_d.size()));
125  }
126 
127  std::stringstream sstr;
128  sstr << "$procdff$" << (autoidx++);
129 
130  RTLIL::Cell *cell = mod->addCell(sstr.str(), "$dffsr");
131  cell->attributes = proc->attributes;
132  cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size());
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);
141 
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");
144 }
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
Definition: rtlil.cc:1353
bool clk_polarity
Definition: abc.cc:98
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
Definition: rtlil.cc:1789
std::map< RTLIL::IdString, RTLIL::Const > parameters
Definition: rtlil.h:856
int size() const
Definition: rtlil.h:1019
#define log_abort()
Definition: log.h:84
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
Definition: rtlil.cc:1809
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
Definition: rtlil.cc:1331
#define NEW_ID
Definition: yosys.h:166
void log(const char *format,...)
Definition: log.cc:180
void append(const RTLIL::SigSpec &signal)
Definition: rtlil.cc:2523
YOSYS_NAMESPACE_BEGIN int autoidx
Definition: yosys.cc:51

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void proc_dff ( RTLIL::Module mod,
RTLIL::Process proc,
ConstEval ce 
)

Definition at line 221 of file proc_dff.cc.

222 {
223  while (1)
224  {
225  RTLIL::SigSpec sig = find_any_lvalue(proc);
226  bool free_sync_level = false;
227 
228  if (sig.size() == 0)
229  break;
230 
231  log("Creating register for signal `%s.%s' using process `%s.%s'.\n",
232  mod->name.c_str(), log_signal(sig), mod->name.c_str(), proc->name.c_str());
233 
236  RTLIL::SyncRule *sync_level = NULL;
237  RTLIL::SyncRule *sync_edge = NULL;
238  RTLIL::SyncRule *sync_always = NULL;
239 
240  std::map<RTLIL::SigSpec, std::set<RTLIL::SyncRule*>> many_async_rules;
241 
242  for (auto sync : proc->syncs)
243  for (auto &action : sync->actions)
244  {
245  if (action.first.extract(sig).size() == 0)
246  continue;
247 
248  if (sync->type == RTLIL::SyncType::ST0 || sync->type == RTLIL::SyncType::ST1) {
249  if (sync_level != NULL && sync_level != sync) {
250  // log_error("Multiple level sensitive events found for this signal!\n");
251  many_async_rules[rstval].insert(sync_level);
252  rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size());
253  }
254  rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size());
255  sig.replace(action.first, action.second, &rstval);
256  sync_level = sync;
257  }
258  else if (sync->type == RTLIL::SyncType::STp || sync->type == RTLIL::SyncType::STn) {
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);
262  sync_edge = sync;
263  }
264  else if (sync->type == RTLIL::SyncType::STa) {
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);
268  sync_always = sync;
269  }
270  else {
271  log_error("Event with any-edge sensitivity found for this signal!\n");
272  }
273 
274  action.first.remove2(sig, &action.second);
275  }
276 
277  if (many_async_rules.size() > 0)
278  {
279  many_async_rules[rstval].insert(sync_level);
280  if (many_async_rules.size() == 1)
281  {
282  sync_level = new RTLIL::SyncRule;
283  sync_level->type = RTLIL::SyncType::ST1;
284  sync_level->signal = mod->addWire(NEW_ID);
285  sync_level->actions.push_back(RTLIL::SigSig(sig, rstval));
286  free_sync_level = true;
287 
288  RTLIL::SigSpec inputs, compare;
289  for (auto &it : many_async_rules[rstval]) {
290  inputs.append(it->signal);
292  }
293  log_assert(inputs.size() == compare.size());
294 
295  RTLIL::Cell *cell = mod->addCell(NEW_ID, "$ne");
296  cell->parameters["\\A_SIGNED"] = RTLIL::Const(false, 1);
297  cell->parameters["\\B_SIGNED"] = RTLIL::Const(false, 1);
298  cell->parameters["\\A_WIDTH"] = RTLIL::Const(inputs.size());
299  cell->parameters["\\B_WIDTH"] = RTLIL::Const(inputs.size());
300  cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
301  cell->setPort("\\A", inputs);
302  cell->setPort("\\B", compare);
303  cell->setPort("\\Y", sync_level->signal);
304 
305  many_async_rules.clear();
306  }
307  else
308  {
309  rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size());
310  sync_level = NULL;
311  }
312  }
313 
314  ce.assign_map.apply(insig);
315  ce.assign_map.apply(rstval);
316  ce.assign_map.apply(sig);
317 
318  if (rstval == sig) {
319  rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size());
320  sync_level = NULL;
321  }
322 
323  if (sync_always) {
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");
327  mod->connect(RTLIL::SigSig(sig, insig));
328  continue;
329  }
330 
331  if (!sync_edge)
332  log_error("Missing edge-sensitive event for this signal!\n");
333 
334  if (many_async_rules.size() > 0)
335  {
336  log_warning("Complex async reset for dff `%s'.\n", log_signal(sig));
337  gen_dffsr_complex(mod, insig, sig, sync_edge->signal, sync_edge->type == RTLIL::SyncType::STp, many_async_rules, proc);
338  }
339  else if (!rstval.is_fully_const() && !ce.eval(rstval))
340  {
341  log_warning("Async reset value `%s' is not constant!\n", log_signal(rstval));
342  gen_dffsr(mod, insig, rstval, sig,
343  sync_edge->type == RTLIL::SyncType::STp,
344  sync_level && sync_level->type == RTLIL::SyncType::ST1,
345  sync_edge->signal, sync_level->signal, proc);
346  }
347  else
348  gen_dff(mod, insig, rstval.as_const(), sig,
349  sync_edge->type == RTLIL::SyncType::STp,
350  sync_level && sync_level->type == RTLIL::SyncType::ST1,
351  sync_edge->signal, sync_level ? &sync_level->signal : NULL, proc);
352 
353  if (free_sync_level)
354  delete sync_level;
355  }
356 }
const char * c_str() const
Definition: rtlil.h:178
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)
Definition: proc_dff.cc:146
void log_warning(const char *format,...)
Definition: log.cc:196
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
Definition: rtlil.cc:1353
RTLIL::SyncType type
Definition: rtlil.h:1144
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
Definition: log.cc:269
bool eval(RTLIL::Cell *cell, RTLIL::SigSpec &undef)
Definition: consteval.h:89
SigMap assign_map
Definition: consteval.h:33
void log_error(const char *format,...)
Definition: log.cc:204
std::map< RTLIL::IdString, RTLIL::Const > parameters
Definition: rtlil.h:856
RTLIL::SigSpec signal
Definition: rtlil.h:1145
int size() const
Definition: rtlil.h:1019
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN RTLIL::SigSpec find_any_lvalue(const RTLIL::Process *proc)
Definition: proc_dff.cc:31
void apply(RTLIL::SigBit &bit) const
Definition: sigtools.h:383
void connect(const RTLIL::SigSig &conn)
Definition: rtlil.cc:1278
#define log_assert(_assert_expr_)
Definition: log.h:85
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
Definition: rtlil.cc:1331
RTLIL::IdString name
Definition: rtlil.h:599
#define NEW_ID
Definition: yosys.h:166
RTLIL::IdString name
Definition: rtlil.h:1154
void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
Definition: rtlil.cc:2297
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)
Definition: proc_dff.cc:193
#define NULL
void log(const char *format,...)
Definition: log.cc:180
std::vector< RTLIL::SyncRule * > syncs
Definition: rtlil.h:1157
void append(const RTLIL::SigSpec &signal)
Definition: rtlil.cc:2523
std::pair< SigSpec, SigSpec > SigSig
Definition: rtlil.h:71
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)
Definition: proc_dff.cc:56

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation