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

Public Member Functions

int register_cone_worker (std::set< RTLIL::Cell * > &celldone, std::map< RTLIL::SigBit, int > &sigdepth, RTLIL::SigBit out)
 
 PerformReduction (SigMap &sigmap, drivers_t &drivers, std::set< std::pair< RTLIL::SigBit, RTLIL::SigBit >> &inv_pairs, std::vector< RTLIL::SigBit > &bits, int cone_size)
 
void analyze_const (std::vector< std::vector< equiv_bit_t >> &results, int idx)
 
void analyze (std::vector< std::set< int >> &results, std::map< int, int > &results_map, std::vector< int > &bucket, std::string indent1, std::string indent2)
 
void analyze (std::vector< std::vector< equiv_bit_t >> &results, int perc)
 

Data Fields

SigMapsigmap
 
drivers_tdrivers
 
std::set< std::pair
< RTLIL::SigBit, RTLIL::SigBit > > & 
inv_pairs
 
ezDefaultSAT ez
 
SatGen satgen
 
std::vector< int > sat_pi
 
std::vector< int > sat_out
 
std::vector< int > sat_def
 
std::vector< RTLIL::SigBitout_bits
 
std::vector< RTLIL::SigBitpi_bits
 
std::vector< bool > out_inverted
 
std::vector< int > out_depth
 
int cone_size
 

Detailed Description

Definition at line 227 of file freduce.cc.

Constructor & Destructor Documentation

PerformReduction::PerformReduction ( SigMap sigmap,
drivers_t drivers,
std::set< std::pair< RTLIL::SigBit, RTLIL::SigBit >> &  inv_pairs,
std::vector< RTLIL::SigBit > &  bits,
int  cone_size 
)
inline

Definition at line 270 of file freduce.cc.

270  :
271  sigmap(sigmap), drivers(drivers), inv_pairs(inv_pairs), satgen(&ez, &sigmap), out_bits(bits), cone_size(cone_size)
272  {
273  satgen.model_undef = true;
274 
275  std::set<RTLIL::Cell*> celldone;
276  std::map<RTLIL::SigBit, int> sigdepth;
277 
278  for (auto &bit : bits) {
279  out_depth.push_back(register_cone_worker(celldone, sigdepth, bit));
280  sat_out.push_back(satgen.importSigSpec(bit).front());
281  sat_def.push_back(ez.NOT(satgen.importUndefSigSpec(bit).front()));
282  }
283 
284  if (inv_mode && cone_size > 0) {
285  if (!ez.solve(sat_out, out_inverted, ez.expression(ezSAT::OpAnd, sat_def)))
286  log_error("Solving for initial model failed!\n");
287  for (size_t i = 0; i < sat_out.size(); i++)
288  if (out_inverted.at(i))
289  sat_out[i] = ez.NOT(sat_out[i]);
290  } else
291  out_inverted = std::vector<bool>(sat_out.size(), false);
292  }
std::set< std::pair< RTLIL::SigBit, RTLIL::SigBit > > & inv_pairs
Definition: freduce.cc:231
int register_cone_worker(std::set< RTLIL::Cell * > &celldone, std::map< RTLIL::SigBit, int > &sigdepth, RTLIL::SigBit out)
Definition: freduce.cc:242
std::vector< int > importSigSpec(RTLIL::SigSpec sig, int timestep=-1)
Definition: satgen.h:78
void log_error(const char *format,...)
Definition: log.cc:204
bool model_undef
Definition: satgen.h:43
SigMap & sigmap
Definition: freduce.cc:229
std::vector< int > importUndefSigSpec(RTLIL::SigSpec sig, int timestep=-1)
Definition: satgen.h:92
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool inv_mode
Definition: freduce.cc:34
std::vector< bool > out_inverted
Definition: freduce.cc:238
ezDefaultSAT ez
Definition: freduce.cc:233
drivers_t & drivers
Definition: freduce.cc:230
std::vector< int > sat_def
Definition: freduce.cc:236
std::vector< int > sat_out
Definition: freduce.cc:236
std::vector< int > out_depth
Definition: freduce.cc:239
std::vector< RTLIL::SigBit > out_bits
Definition: freduce.cc:237

+ Here is the call graph for this function:

Member Function Documentation

void PerformReduction::analyze ( std::vector< std::set< int >> &  results,
std::map< int, int > &  results_map,
std::vector< int > &  bucket,
std::string  indent1,
std::string  indent2 
)
inline

Definition at line 338 of file freduce.cc.

339  {
340  std::string indent = indent1 + indent2;
341  const char *indt = indent.c_str();
342 
343  if (bucket.size() <= 1)
344  return;
345 
346  if (verbose_level == 1)
347  log("%s Trying to shatter bucket with %d signals.\n", indt, int(bucket.size()));
348 
349  if (verbose_level > 1) {
350  std::vector<RTLIL::SigBit> bucket_sigbits;
351  for (int idx : bucket)
352  bucket_sigbits.push_back(out_bits[idx]);
353  log("%s Trying to shatter bucket with %d signals: %s\n", indt, int(bucket.size()), log_signal(bucket_sigbits));
354  }
355 
356  std::vector<int> sat_set_list, sat_clr_list;
357  for (int idx : bucket) {
358  sat_set_list.push_back(ez.AND(sat_out[idx], sat_def[idx]));
359  sat_clr_list.push_back(ez.AND(ez.NOT(sat_out[idx]), sat_def[idx]));
360  }
361 
362  std::vector<int> modelVars = sat_out;
363  std::vector<bool> model;
364 
365  modelVars.insert(modelVars.end(), sat_def.begin(), sat_def.end());
366  if (verbose_level >= 2)
367  modelVars.insert(modelVars.end(), sat_pi.begin(), sat_pi.end());
368 
369  if (ez.solve(modelVars, model, ez.expression(ezSAT::OpOr, sat_set_list), ez.expression(ezSAT::OpOr, sat_clr_list)))
370  {
371  int iter_count = 1;
372 
373  while (1)
374  {
375  sat_set_list.clear();
376  sat_clr_list.clear();
377 
378  std::vector<int> sat_def_list;
379 
380  for (int idx : bucket)
381  if (!model[sat_out.size() + idx]) {
382  sat_set_list.push_back(ez.AND(sat_out[idx], sat_def[idx]));
383  sat_clr_list.push_back(ez.AND(ez.NOT(sat_out[idx]), sat_def[idx]));
384  } else {
385  sat_def_list.push_back(sat_def[idx]);
386  }
387 
388  if (!ez.solve(modelVars, model, ez.expression(ezSAT::OpOr, sat_set_list), ez.expression(ezSAT::OpOr, sat_clr_list), ez.expression(ezSAT::OpAnd, sat_def_list)))
389  break;
390  iter_count++;
391  }
392 
393  if (verbose_level >= 1) {
394  int count_set = 0, count_clr = 0, count_undef = 0;
395  for (int idx : bucket)
396  if (!model[sat_out.size() + idx])
397  count_undef++;
398  else if (model[idx])
399  count_set++;
400  else
401  count_clr++;
402  log("%s After %d iterations: %d set vs. %d clr vs %d undef\n", indt, iter_count, count_set, count_clr, count_undef);
403  }
404 
405  if (verbose_level >= 2) {
406  for (size_t i = 0; i < pi_bits.size(); i++)
407  log("%s -> PI %c == %s\n", indt, model[2*sat_out.size() + i] ? '1' : '0', log_signal(pi_bits[i]));
408  for (int idx : bucket)
409  log("%s -> OUT %c == %s%s\n", indt, model[sat_out.size() + idx] ? model[idx] ? '1' : '0' : 'x',
410  out_inverted.at(idx) ? "~" : "", log_signal(out_bits[idx]));
411  }
412 
413  std::vector<int> buckets_a;
414  std::vector<int> buckets_b;
415 
416  for (int idx : bucket) {
417  if (!model[sat_out.size() + idx] || model[idx])
418  buckets_a.push_back(idx);
419  if (!model[sat_out.size() + idx] || !model[idx])
420  buckets_b.push_back(idx);
421  }
422  analyze(results, results_map, buckets_a, indent1 + ".", indent2 + " ");
423  analyze(results, results_map, buckets_b, indent1 + "x", indent2 + " ");
424  }
425  else
426  {
427  std::vector<int> undef_slaves;
428 
429  for (int idx : bucket) {
430  std::vector<int> sat_def_list;
431  for (int idx2 : bucket)
432  if (idx != idx2)
433  sat_def_list.push_back(sat_def[idx2]);
434  if (ez.solve(ez.NOT(sat_def[idx]), ez.expression(ezSAT::OpOr, sat_def_list)))
435  undef_slaves.push_back(idx);
436  }
437 
438  if (undef_slaves.size() == bucket.size()) {
439  if (verbose_level >= 1)
440  log("%s Complex undef overlap. None of the signals covers the others.\n", indt);
441  // FIXME: We could try to further shatter a group with complex undef overlaps
442  return;
443  }
444 
445  for (int idx : undef_slaves)
446  out_depth[idx] = std::numeric_limits<int>::max();
447 
448  if (verbose_level >= 1) {
449  log("%s Found %d equivialent signals:", indt, int(bucket.size()));
450  for (int idx : bucket)
451  log("%s%s%s", idx == bucket.front() ? " " : ", ", out_inverted[idx] ? "~" : "", log_signal(out_bits[idx]));
452  log("\n");
453  }
454 
455  int result_idx = -1;
456  for (int idx : bucket) {
457  if (results_map.count(idx) == 0)
458  continue;
459  if (result_idx == -1) {
460  result_idx = results_map.at(idx);
461  continue;
462  }
463  int result_idx2 = results_map.at(idx);
464  results[result_idx].insert(results[result_idx2].begin(), results[result_idx2].end());
465  for (int idx2 : results[result_idx2])
466  results_map[idx2] = result_idx;
467  results[result_idx2].clear();
468  }
469 
470  if (result_idx == -1) {
471  result_idx = results.size();
472  results.push_back(std::set<int>());
473  }
474 
475  results[result_idx].insert(bucket.begin(), bucket.end());
476  }
477  }
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
Definition: log.cc:269
static std::string idx(std::string str)
Definition: test_autotb.cc:57
std::vector< RTLIL::SigBit > pi_bits
Definition: freduce.cc:237
std::vector< bool > out_inverted
Definition: freduce.cc:238
int verbose_level
Definition: freduce.cc:35
ezDefaultSAT ez
Definition: freduce.cc:233
std::vector< int > sat_def
Definition: freduce.cc:236
void log(const char *format,...)
Definition: log.cc:180
std::vector< int > sat_out
Definition: freduce.cc:236
std::vector< int > out_depth
Definition: freduce.cc:239
void analyze(std::vector< std::set< int >> &results, std::map< int, int > &results_map, std::vector< int > &bucket, std::string indent1, std::string indent2)
Definition: freduce.cc:338
std::vector< RTLIL::SigBit > out_bits
Definition: freduce.cc:237
std::vector< int > sat_pi
Definition: freduce.cc:236

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PerformReduction::analyze ( std::vector< std::vector< equiv_bit_t >> &  results,
int  perc 
)
inline

Definition at line 479 of file freduce.cc.

480  {
481  std::vector<int> bucket;
482  for (size_t i = 0; i < sat_out.size(); i++)
483  bucket.push_back(i);
484 
485  std::vector<std::set<int>> results_buf;
486  std::map<int, int> results_map;
487  analyze(results_buf, results_map, bucket, stringf("[%2d%%] %d ", perc, cone_size), "");
488 
489  for (auto &r : results_buf)
490  {
491  if (r.size() <= 1)
492  continue;
493 
494  if (verbose_level >= 1) {
495  std::vector<RTLIL::SigBit> r_sigbits;
496  for (int idx : r)
497  r_sigbits.push_back(out_bits[idx]);
498  log(" Found group of %d equivialent signals: %s\n", int(r.size()), log_signal(r_sigbits));
499  }
500 
501  std::vector<int> undef_slaves;
502 
503  for (int idx : r) {
504  std::vector<int> sat_def_list;
505  for (int idx2 : r)
506  if (idx != idx2)
507  sat_def_list.push_back(sat_def[idx2]);
508  if (ez.solve(ez.NOT(sat_def[idx]), ez.expression(ezSAT::OpOr, sat_def_list)))
509  undef_slaves.push_back(idx);
510  }
511 
512  if (undef_slaves.size() == bucket.size()) {
513  if (verbose_level >= 1)
514  log(" Complex undef overlap. None of the signals covers the others.\n");
515  // FIXME: We could try to further shatter a group with complex undef overlaps
516  return;
517  }
518 
519  for (int idx : undef_slaves)
520  out_depth[idx] = std::numeric_limits<int>::max();
521 
522  std::vector<equiv_bit_t> result;
523 
524  for (int idx : r) {
525  equiv_bit_t bit;
526  bit.depth = out_depth[idx];
527  bit.inverted = out_inverted[idx];
528  bit.drv = drivers.count(out_bits[idx]) ? drivers.at(out_bits[idx]).first : NULL;
529  bit.bit = out_bits[idx];
530  result.push_back(bit);
531  }
532 
533  std::sort(result.begin(), result.end());
534 
535  if (result.front().inverted)
536  for (auto &bit : result)
537  bit.inverted = !bit.inverted;
538 
539  for (size_t i = 1; i < result.size(); i++) {
540  std::pair<RTLIL::SigBit, RTLIL::SigBit> p(result[0].bit, result[i].bit);
541  if (inv_pairs.count(p) != 0)
542  result.erase(result.begin() + i);
543  }
544 
545  if (result.size() > 1)
546  results.push_back(result);
547  }
548  }
std::set< std::pair< RTLIL::SigBit, RTLIL::SigBit > > & inv_pairs
Definition: freduce.cc:231
std::string stringf(const char *fmt,...)
Definition: yosys.cc:58
void sort(T *array, int size, LessThan lt)
Definition: Sort.h:57
RTLIL::SigBit bit
Definition: freduce.cc:44
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
Definition: log.cc:269
static std::string idx(std::string str)
Definition: test_autotb.cc:57
bool inverted
Definition: freduce.cc:42
int depth
Definition: freduce.cc:41
std::vector< bool > out_inverted
Definition: freduce.cc:238
int verbose_level
Definition: freduce.cc:35
ezDefaultSAT ez
Definition: freduce.cc:233
#define NULL
drivers_t & drivers
Definition: freduce.cc:230
std::vector< int > sat_def
Definition: freduce.cc:236
void log(const char *format,...)
Definition: log.cc:180
std::vector< int > sat_out
Definition: freduce.cc:236
std::vector< int > out_depth
Definition: freduce.cc:239
void analyze(std::vector< std::set< int >> &results, std::map< int, int > &results_map, std::vector< int > &bucket, std::string indent1, std::string indent2)
Definition: freduce.cc:338
RTLIL::Cell * drv
Definition: freduce.cc:43
std::vector< RTLIL::SigBit > out_bits
Definition: freduce.cc:237

+ Here is the call graph for this function:

void PerformReduction::analyze_const ( std::vector< std::vector< equiv_bit_t >> &  results,
int  idx 
)
inline

Definition at line 294 of file freduce.cc.

295  {
296  if (verbose_level == 1)
297  log(" Finding const value for %s.\n", log_signal(out_bits[idx]));
298 
299  bool can_be_set = ez.solve(ez.AND(sat_out[idx], sat_def[idx]));
300  bool can_be_clr = ez.solve(ez.AND(ez.NOT(sat_out[idx]), sat_def[idx]));
301  log_assert(!can_be_set || !can_be_clr);
302 
304  if (can_be_set)
305  value = RTLIL::State::S1;
306  if (can_be_clr)
307  value = RTLIL::State::S0;
308  if (verbose_level == 1)
309  log(" Constant value for this signal: %s\n", log_signal(value));
310 
311  int result_idx = -1;
312  for (size_t i = 0; i < results.size(); i++) {
313  if (results[i].front().bit == value) {
314  result_idx = i;
315  break;
316  }
317  }
318 
319  if (result_idx == -1) {
320  result_idx = results.size();
321  results.push_back(std::vector<equiv_bit_t>());
322  equiv_bit_t bit;
323  bit.depth = 0;
324  bit.inverted = false;
325  bit.drv = NULL;
326  bit.bit = value;
327  results.back().push_back(bit);
328  }
329 
330  equiv_bit_t bit;
331  bit.depth = 1;
332  bit.inverted = false;
333  bit.drv = drivers.count(out_bits[idx]) ? drivers.at(out_bits[idx]).first : NULL;
334  bit.bit = out_bits[idx];
335  results[result_idx].push_back(bit);
336  }
RTLIL::SigBit bit
Definition: freduce.cc:44
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
Definition: log.cc:269
static std::string idx(std::string str)
Definition: test_autotb.cc:57
bool inverted
Definition: freduce.cc:42
#define log_assert(_assert_expr_)
Definition: log.h:85
int depth
Definition: freduce.cc:41
int verbose_level
Definition: freduce.cc:35
ezDefaultSAT ez
Definition: freduce.cc:233
#define NULL
drivers_t & drivers
Definition: freduce.cc:230
std::vector< int > sat_def
Definition: freduce.cc:236
void log(const char *format,...)
Definition: log.cc:180
std::vector< int > sat_out
Definition: freduce.cc:236
RTLIL::Cell * drv
Definition: freduce.cc:43
std::vector< RTLIL::SigBit > out_bits
Definition: freduce.cc:237

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int PerformReduction::register_cone_worker ( std::set< RTLIL::Cell * > &  celldone,
std::map< RTLIL::SigBit, int > &  sigdepth,
RTLIL::SigBit  out 
)
inline

Definition at line 242 of file freduce.cc.

243  {
244  if (out.wire == NULL)
245  return 0;
246  if (sigdepth.count(out) != 0)
247  return sigdepth.at(out);
248 
249  if (drivers.count(out) != 0) {
250  std::pair<RTLIL::Cell*, std::set<RTLIL::SigBit>> &drv = drivers.at(out);
251  if (celldone.count(drv.first) == 0) {
252  if (!satgen.importCell(drv.first))
253  log_error("Can't create SAT model for cell %s (%s)!\n", RTLIL::id2cstr(drv.first->name), RTLIL::id2cstr(drv.first->type));
254  celldone.insert(drv.first);
255  }
256  int max_child_depth = 0;
257  for (auto &bit : drv.second)
258  max_child_depth = std::max(register_cone_worker(celldone, sigdepth, bit), max_child_depth);
259  sigdepth[out] = max_child_depth + 1;
260  } else {
261  pi_bits.push_back(out);
262  sat_pi.push_back(satgen.importSigSpec(out).front());
263  ez.assume(ez.NOT(satgen.importUndefSigSpec(out).front()));
264  sigdepth[out] = 0;
265  }
266 
267  return sigdepth.at(out);
268  }
RTLIL::Wire * wire
Definition: rtlil.h:907
int register_cone_worker(std::set< RTLIL::Cell * > &celldone, std::map< RTLIL::SigBit, int > &sigdepth, RTLIL::SigBit out)
Definition: freduce.cc:242
std::vector< int > importSigSpec(RTLIL::SigSpec sig, int timestep=-1)
Definition: satgen.h:78
void log_error(const char *format,...)
Definition: log.cc:204
std::vector< int > importUndefSigSpec(RTLIL::SigSpec sig, int timestep=-1)
Definition: satgen.h:92
std::vector< RTLIL::SigBit > pi_bits
Definition: freduce.cc:237
static const char * id2cstr(const RTLIL::IdString &str)
Definition: rtlil.h:267
ezDefaultSAT ez
Definition: freduce.cc:233
#define NULL
drivers_t & drivers
Definition: freduce.cc:230
bool importCell(RTLIL::Cell *cell, int timestep=-1)
Definition: satgen.h:203
std::vector< int > sat_pi
Definition: freduce.cc:236

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Field Documentation

int PerformReduction::cone_size

Definition at line 240 of file freduce.cc.

drivers_t& PerformReduction::drivers

Definition at line 230 of file freduce.cc.

ezDefaultSAT PerformReduction::ez

Definition at line 233 of file freduce.cc.

std::set<std::pair<RTLIL::SigBit, RTLIL::SigBit> >& PerformReduction::inv_pairs

Definition at line 231 of file freduce.cc.

std::vector<RTLIL::SigBit> PerformReduction::out_bits

Definition at line 237 of file freduce.cc.

std::vector<int> PerformReduction::out_depth

Definition at line 239 of file freduce.cc.

std::vector<bool> PerformReduction::out_inverted

Definition at line 238 of file freduce.cc.

std::vector<RTLIL::SigBit> PerformReduction::pi_bits

Definition at line 237 of file freduce.cc.

std::vector<int> PerformReduction::sat_def

Definition at line 236 of file freduce.cc.

std::vector<int> PerformReduction::sat_out

Definition at line 236 of file freduce.cc.

std::vector<int> PerformReduction::sat_pi

Definition at line 236 of file freduce.cc.

SatGen PerformReduction::satgen

Definition at line 234 of file freduce.cc.

SigMap& PerformReduction::sigmap

Definition at line 229 of file freduce.cc.


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