ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
rrrBddMspfAnalyzer.h
Go to the documentation of this file.
1#pragma once
2
3#include "rrrParameter.h"
4#include "rrrUtils.h"
5#include "rrrBddManager.h"
6
8
9namespace rrr {
10
11 template <typename Ntk>
13 private:
14 // aliases
15 using lit = int;
16 static constexpr lit LitMax = 0xffffffff;
17
18 // pointer to network
19 Ntk *pNtk;
20
21 // parameters
22 int nVerbose;
23
24 // data
25 bool fInitialized;
26 NewBdd::Man *pBdd;
27 std::vector<lit> vFs;
28 std::vector<lit> vGs;
29 std::vector<std::vector<lit>> vvCs;
30 bool fUpdate;
31 std::vector<bool> vUpdates;
32 std::vector<bool> vGUpdates;
33 std::vector<bool> vCUpdates;
34 std::vector<bool> vVisits;
35
36 // backups
37 std::vector<BddMspfAnalyzer> vBackups;
38
39 // stats
40 uint64_t nNodesOld;
41 uint64_t nNodesAccumulated;
42 double durationSimulation;
43 double durationPf;
44 double durationCheck;
45 double durationReorder;
46
47 // BDD utils
48 void IncRef(lit x) const;
49 void DecRef(lit x) const;
50 void Assign(lit &x, lit y) const;
51 void CopyVec(std::vector<lit> &x, std::vector<lit> const &y) const;
52 void DelVec(std::vector<lit> &v) const;
53 void CopyVecVec(std::vector<std::vector<lit>> &x, std::vector<std::vector<lit>> const &y) const;
54 void DelVecVec(std::vector<std::vector<lit>> &v) const;
55 lit Xor(lit x, lit y) const;
56
57 // callback
58 void ActionCallback(Action const &action);
59
60 // allocation
61 void Allocate();
62
63 // simulation
64 bool SimulateNode(int id, std::vector<lit> &v) const;
65 void Simulate();
66
67 // PF computation
68 bool ComputeReconvergentG(int id);
69 bool ComputeG(int id);
70 void ComputeC(int id);
71 bool ComputeCDebug(int id);
72 void MspfNode(int id);
73 void Mspf(int id = -1, bool fC = true);
74
75 // preparation
76 void Reset(bool fReuse = false);
77 void Initialize();
78
79 // save & load
80 void Save(int slot);
81 void Load(int slot);
82 void PopBack();
83
84 public:
85 // constructors
87 BddMspfAnalyzer(Parameter const *pPar);
89 void AssignNetwork(Ntk *pNtk_, bool fReuse);
90
91 // checks
92 bool CheckRedundancy(int id, int idx);
93 bool CheckFeasibility(int id, int fi, bool c);
94
95 // summary
96 void ResetSummary();
99 };
100
101 /* {{{ BDD utils */
102
103 template <typename Ntk>
104 inline void BddMspfAnalyzer<Ntk>::IncRef(lit x) const {
105 if(x != LitMax) {
106 pBdd->IncRef(x);
107 }
108 }
109
110 template <typename Ntk>
111 inline void BddMspfAnalyzer<Ntk>::DecRef(lit x) const {
112 if(x != LitMax) {
113 pBdd->DecRef(x);
114 }
115 }
116
117 template <typename Ntk>
118 inline void BddMspfAnalyzer<Ntk>::Assign(lit &x, lit y) const {
119 DecRef(x);
120 x = y;
121 IncRef(x);
122 }
123
124 template <typename Ntk>
125 inline void BddMspfAnalyzer<Ntk>::CopyVec(std::vector<lit> &x, std::vector<lit> const &y) const {
126 for(size_t i = y.size(); i < x.size(); i++) {
127 DecRef(x[i]);
128 }
129 x.resize(y.size(), LitMax);
130 for(size_t i = 0; i < y.size(); i++) {
131 if(x[i] != y[i]) {
132 DecRef(x[i]);
133 x[i] = y[i];
134 IncRef(x[i]);
135 }
136 }
137 }
138
139 template <typename Ntk>
140 inline void BddMspfAnalyzer<Ntk>::DelVec(std::vector<lit> &v) const {
141 for(lit x: v) {
142 DecRef(x);
143 }
144 v.clear();
145 }
146
147 template <typename Ntk>
148 inline void BddMspfAnalyzer<Ntk>::CopyVecVec(std::vector<std::vector<lit>> &x, std::vector<std::vector<lit>> const &y) const {
149 for(size_t i = y.size(); i < x.size(); i++) {
150 DelVec(x[i]);
151 }
152 x.resize(y.size());
153 for(size_t i = 0; i < y.size(); i++) {
154 CopyVec(x[i], y[i]);
155 }
156 }
157
158 template <typename Ntk>
159 inline void BddMspfAnalyzer<Ntk>::DelVecVec(std::vector<std::vector<lit>> &v) const {
160 for(size_t i = 0; i < v.size(); i++) {
161 DelVec(v[i]);
162 }
163 v.clear();
164 }
165
166 template <typename Ntk>
167 inline typename BddMspfAnalyzer<Ntk>::lit BddMspfAnalyzer<Ntk>::Xor(lit x, lit y) const {
168 lit f = pBdd->And(x, pBdd->LitNot(y));
169 pBdd->IncRef(f);
170 lit g = pBdd->And(pBdd->LitNot(x), y);
171 pBdd->IncRef(g);
172 lit r = pBdd->Or(f, g);
173 pBdd->DecRef(f);
174 pBdd->DecRef(g);
175 return r;
176 }
177
178 /* }}} */
179
180 /* {{{ Callback */
181
182 template <typename Ntk>
183 void BddMspfAnalyzer<Ntk>::ActionCallback(Action const &action) {
184 switch(action.type) {
185 case REMOVE_FANIN:
186 assert(fInitialized);
187 fUpdate = true;
188 std::fill(vVisits.begin(), vVisits.end(), false);
189 vUpdates[action.id] = true;
190 vCUpdates[action.id] = true;
191 vGUpdates[action.fi] = true;
192 DecRef(vvCs[action.id][action.idx]);
193 vvCs[action.id].erase(vvCs[action.id].begin() + action.idx);
194 break;
195 case REMOVE_UNUSED:
196 if(fInitialized) {
197 if(vGUpdates[action.id] || vCUpdates[action.id]) {
198 for(int fi: action.vFanins) {
199 vGUpdates[fi] = true;
200 }
201 }
202 Assign(vGs[action.id], LitMax);
203 DelVec(vvCs[action.id]);
204 }
205 break;
206 case REMOVE_BUFFER:
207 if(fInitialized) {
208 if(vUpdates[action.id]) {
209 fUpdate = true;
210 for(int fo: action.vFanouts) {
211 vUpdates[fo] = true;
212 vCUpdates[fo] = true;
213 }
214 }
215 if(vGUpdates[action.id] || vCUpdates[action.id]) {
216 vGUpdates[action.fi] = true;
217 }
218 Assign(vGs[action.id], LitMax);
219 DelVec(vvCs[action.id]);
220 }
221 break;
222 case REMOVE_CONST:
223 if(fInitialized) {
224 if(vUpdates[action.id]) {
225 fUpdate = true;
226 for(int fo: action.vFanouts) {
227 vUpdates[fo] = true;
228 vCUpdates[fo] = true;
229 }
230 }
231 for(int fi: action.vFanins) {
232 vGUpdates[fi] = true;
233 }
234 }
235 break;
236 case ADD_FANIN:
237 assert(fInitialized);
238 fUpdate = true;
239 std::fill(vVisits.begin(), vVisits.end(), false);
240 vUpdates[action.id] = true;
241 vCUpdates[action.id] = true;
242 vvCs[action.id].insert(vvCs[action.id].begin() + action.idx, LitMax);
243 break;
244 case TRIVIAL_COLLAPSE:
245 if(fInitialized) {
246 if(vGUpdates[action.fi] || vCUpdates[action.fi]) {
247 vCUpdates[action.id] = true;
248 }
249 std::vector<lit>::iterator it = vvCs[action.id].begin() + action.idx;
250 DecRef(*it);
251 it = vvCs[action.id].erase(it);
252 vvCs[action.id].insert(it, vvCs[action.fi].begin(), vvCs[action.fi].end());
253 vvCs[action.fi].clear();
254 Assign(vFs[action.fi], LitMax);
255 Assign(vGs[action.fi], LitMax);
256 }
257 break;
259 if(fInitialized) {
260 Allocate();
261 SimulateNode(action.fi, vFs);
262 // time of this simulation is not measured for simplicity sake
263 assert(vGs[action.fi] == LitMax);
264 std::vector<lit>::iterator it = vvCs[action.id].begin() + action.idx;
265 assert(vvCs[action.fi].empty());
266 vvCs[action.fi].insert(vvCs[action.fi].begin(), it, vvCs[action.id].end());
267 vvCs[action.id].erase(it, vvCs[action.id].end());
268 assert(vvCs[action.id].size() == action.idx);
269 if(!vGUpdates[action.id] && !vCUpdates[action.id]) {
270 // recompute here only when updates are unlikely to happen
271 if(pBdd->IsConst1(vGs[action.id])) {
272 Assign(vGs[action.fi], pBdd->Const1());
273 } else {
274 lit x = pBdd->Const1();
275 IncRef(x);
276 for(int idx2 = 0; idx2 < action.idx; idx2++) {
277 int fi = pNtk->GetFanin(action.id, idx2);
278 bool c = pNtk->GetCompl(action.id, idx2);
279 Assign(x, pBdd->And(x, pBdd->LitNotCond(vFs[fi], c)));
280 }
281 Assign(vGs[action.fi], pBdd->Or(pBdd->LitNot(x), vGs[action.id]));
282 DecRef(x);
283 }
284 } else {
285 // otherwise mark the node for future update
286 vCUpdates[action.id] = true;
287 }
288 vvCs[action.id].resize(action.idx + 1, LitMax);
289 Assign(vvCs[action.id][action.idx], vGs[action.fi]);
290 vUpdates[action.fi] = false;
291 vGUpdates[action.fi] = false;
292 vCUpdates[action.fi] = false;
293 }
294 break;
295 case SORT_FANINS:
296 if(fInitialized) {
297 std::vector<lit> vCs = vvCs[action.id];
298 vvCs[action.id].clear();
299 for(int index: action.vIndices) {
300 vvCs[action.id].push_back(vCs[index]);
301 }
302 }
303 break;
304 case READ:
305 Reset(!action.fNew);
306 break;
307 case SAVE:
308 Save(action.idx);
309 break;
310 case LOAD:
311 Load(action.idx);
312 break;
313 case POP_BACK:
314 PopBack();
315 break;
316 default:
317 assert(0);
318 }
319 }
320
321 /* }}} */
322
323 /* {{{ Allocation */
324
325 template <typename Ntk>
326 void BddMspfAnalyzer<Ntk>::Allocate() {
327 int nNodes = pNtk->GetNumNodes();
328 vFs.resize(nNodes, LitMax);
329 vGs.resize(nNodes, LitMax);
330 vvCs.resize(nNodes);
331 vUpdates.resize(nNodes);
332 vGUpdates.resize(nNodes);
333 vCUpdates.resize(nNodes);
334 vVisits.resize(nNodes);
335 }
336
337 /* }}} */
338
339 /* {{{ Simulation */
340
341 template <typename Ntk>
342 inline bool BddMspfAnalyzer<Ntk>::SimulateNode(int id, std::vector<lit> &v) const {
343 if(nVerbose) {
344 std::cout << "simulating node " << id << std::endl;
345 }
346 lit x = pBdd->Const1();
347 IncRef(x);
348 pNtk->ForEachFanin(id, [&](int fi, bool c) {
349 Assign(x, pBdd->And(x, pBdd->LitNotCond(v[fi], c)));
350 });
351 if(pBdd->LitIsEq(x, v[id])) {
352 DecRef(x);
353 return false;
354 }
355 Assign(v[id], x);
356 DecRef(x);
357 return true;
358 }
359
360 template <typename Ntk>
361 void BddMspfAnalyzer<Ntk>::Simulate() {
362 time_point timeStart = GetCurrentTime();
363 if(nVerbose) {
364 std::cout << "symbolic simulation with BDD" << std::endl;
365 }
366 pNtk->ForEachInt([&](int id) {
367 if(vUpdates[id]) {
368 if(SimulateNode(id, vFs)) {
369 pNtk->ForEachFanout(id, false, [&](int fo) {
370 vUpdates[fo] = true;
371 vCUpdates[fo] = true;
372 });
373 }
374 vUpdates[id] = false;
375 }
376 });
377 durationSimulation += Duration(timeStart, GetCurrentTime());
378 }
379
380 /* }}} */
381
382 /* {{{ MSPF computation */
383
384 template <typename pNtk>
385 inline bool BddMspfAnalyzer<pNtk>::ComputeReconvergentG(int id) {
386 std::vector<lit> v;
387 CopyVec(v, vFs);
388 v[id] = pBdd->LitNot(v[id]);
389 pNtk->ForEachTfoUpdate(id, false, [&](int fo) {
390 return SimulateNode(fo, v);
391 });
392 lit x = pBdd->Const1();
393 IncRef(x);
394 pNtk->ForEachPoDriver([&](int fi) {
395 lit y = Xor(vFs[fi], v[fi]);
396 IncRef(y);
397 Assign(x, pBdd->And(x, pBdd->LitNot(y)));
398 DecRef(y);
399 });
400 if(pBdd->LitIsEq(vGs[id], x)) {
401 DecRef(x);
402 DelVec(v);
403 return false;
404 }
405 Assign(vGs[id], x);
406 DecRef(x);
407 DelVec(v);
408 return true;
409 }
410
411 template <typename pNtk>
412 inline bool BddMspfAnalyzer<pNtk>::ComputeG(int id) {
413 if(pNtk->GetNumFanouts(id) == 0) {
414 if(pBdd->IsConst1(vGs[id])) {
415 return false;
416 }
417 Assign(vGs[id], pBdd->Const1());
418 return true;
419 }
420 lit x = pBdd->Const1();
421 IncRef(x);
422 pNtk->ForEachFanoutRidx(id, true, [&](int fo, int idx) {
423 Assign(x, pBdd->And(x, vvCs[fo][idx]));
424 });
425 if(pBdd->LitIsEq(vGs[id], x)) {
426 DecRef(x);
427 return false;
428 }
429 Assign(vGs[id], x);
430 DecRef(x);
431 return true;
432 }
433
434 template <typename pNtk>
435 inline void BddMspfAnalyzer<pNtk>::ComputeC(int id) {
436 int nFanins = pNtk->GetNumFanins(id);
437 assert(vvCs[id].size() == nFanins);
438 if(pBdd->IsConst1(vGs[id])) {
439 for(int idx = 0; idx < nFanins; idx++) {
440 if(!pBdd->IsConst1(vvCs[id][idx])) {
441 Assign(vvCs[id][idx], pBdd->Const1());
442 int fi = pNtk->GetFanin(id, idx);
443 vGUpdates[fi] = true;
444 }
445 }
446 return;
447 }
448 for(int idx = 0; idx < nFanins; idx++) {
449 lit x = pBdd->Const1();
450 IncRef(x);
451 for(int idx2 = 0; idx2 < nFanins; idx2++) {
452 if(idx2 != idx) {
453 int fi = pNtk->GetFanin(id, idx2);
454 bool c = pNtk->GetCompl(id, idx2);
455 Assign(x, pBdd->And(x, pBdd->LitNotCond(vFs[fi], c)));
456 }
457 }
458 Assign(x, pBdd->Or(pBdd->LitNot(x), vGs[id]));
459 if(!pBdd->LitIsEq(vvCs[id][idx], x)) {
460 Assign(vvCs[id][idx], x);
461 int fi = pNtk->GetFanin(id, idx);
462 vGUpdates[fi] = true;
463 }
464 DecRef(x);
465 }
466 }
467
468 template <typename pNtk>
469 inline bool BddMspfAnalyzer<pNtk>::ComputeCDebug(int id) {
470 bool fUpdated = false;
471 int nFanins = pNtk->GetNumFanins(id);
472 assert(vvCs[id].size() == nFanins);
473 if(pBdd->IsConst1(vGs[id])) {
474 for(int idx = 0; idx < nFanins; idx++) {
475 if(!pBdd->IsConst1(vvCs[id][idx])) {
476 Assign(vvCs[id][idx], pBdd->Const1());
477 int fi = pNtk->GetFanin(id, idx);
478 vGUpdates[fi] = true;
479 fUpdated = true;
480 }
481 }
482 return fUpdated;
483 }
484 for(int idx = 0; idx < nFanins; idx++) {
485 lit x = pBdd->Const1();
486 IncRef(x);
487 for(int idx2 = 0; idx2 < nFanins; idx2++) {
488 if(idx2 != idx) {
489 int fi = pNtk->GetFanin(id, idx2);
490 bool c = pNtk->GetCompl(id, idx2);
491 Assign(x, pBdd->And(x, pBdd->LitNotCond(vFs[fi], c)));
492 }
493 }
494 Assign(x, pBdd->Or(pBdd->LitNot(x), vGs[id]));
495 if(!pBdd->LitIsEq(vvCs[id][idx], x)) {
496 Assign(vvCs[id][idx], x);
497 int fi = pNtk->GetFanin(id, idx);
498 vGUpdates[fi] = true;
499 fUpdated = true;
500 }
501 DecRef(x);
502 }
503 return fUpdated;
504 }
505
506 template <typename pNtk>
507 void BddMspfAnalyzer<pNtk>::MspfNode(int id) {
508 if(vGUpdates[id]) {
509 if(pNtk->IsReconvergent(id)) {
510 if(nVerbose) {
511 std::cout << "computing reconvergent node " << id << " G " << std::endl;
512 }
513 if(ComputeReconvergentG(id)) {
514 vCUpdates[id] = true;
515 }
516 } else {
517 if(nVerbose) {
518 std::cout << "computing node " << id << " G " << std::endl;
519 }
520 if(ComputeG(id)) {
521 vCUpdates[id] = true;
522 }
523 }
524 vGUpdates[id] = false;
525 } else if(!vVisits[id] && pNtk->IsReconvergent(id)) {
526 if(nVerbose) {
527 std::cout << "computing unvisited reconvergent node " << id << " G " << std::endl;
528 }
529 if(ComputeReconvergentG(id)) {
530 vCUpdates[id] = true;
531 }
532 }
533 if(vCUpdates[id]) {
534 if(nVerbose) {
535 std::cout << "computing node " << id << " C " << std::endl;
536 }
537 ComputeC(id);
538 vCUpdates[id] = false;
539 }
540 vVisits[id] = true;
541 }
542
543 template <typename pNtk>
544 void BddMspfAnalyzer<pNtk>::Mspf(int id, bool fC) {
545 time_point timeStart = GetCurrentTime();
546 if(id != -1) {
547 pNtk->ForEachTfoReverse(id, false, [&](int fo) {
548 MspfNode(fo);
549 });
550 bool fCUpdate = vCUpdates[id];
551 if(!fC) {
552 vCUpdates[id] = false;
553 }
554 MspfNode(id);
555 if(!fC) {
556 vCUpdates[id] = fCUpdate;
557 }
558 } else {
559 pNtk->ForEachIntReverse([&](int id) {
560 MspfNode(id);
561 });
562 }
563 durationPf += Duration(timeStart, GetCurrentTime());
564 }
565
566 /* }}} */
567
568 /* {{{ Preparation */
569
570 template <typename Ntk>
571 void BddMspfAnalyzer<Ntk>::Reset(bool fReuse) {
572 while(!vBackups.empty()) {
573 PopBack();
574 }
575 DelVec(vFs);
576 DelVec(vGs);
577 DelVecVec(vvCs);
578 fInitialized = false;
579 fUpdate = false;
580 vUpdates.clear();
581 vGUpdates.clear();
582 vCUpdates.clear();
583 vVisits.clear();
584 if(!fReuse) {
585 nNodesOld = 0;
586 if(pBdd) {
587 nNodesAccumulated += pBdd->GetNumTotalCreatedNodes();
588 }
589 delete pBdd;
590 pBdd = NULL;
591 }
592 }
593
594 template <typename Ntk>
595 void BddMspfAnalyzer<Ntk>::Initialize() {
596 bool fUseReo = false;
597 if(!pBdd) {
598 NewBdd::Param Par;
599 Par.nObjsMaxLog = 25;
600 Par.nCacheMaxLog = 20;
601 Par.fCountOnes = false;
602 Par.nGbc = 1;
603 Par.nReo = 4000;
604 pBdd = new NewBdd::Man(pNtk->GetNumPis(), Par);
605 fUseReo = true;
606 }
607 assert(pBdd->GetNumVars() == pNtk->GetNumPis());
608 Allocate();
609 Assign(vFs[0], pBdd->Const0());
610 int idx = 0;
611 pNtk->ForEachPi([&](int id) {
612 Assign(vFs[id], pBdd->IthVar(idx));
613 idx++;
614 });
615 pNtk->ForEachInt([&](int id) {
616 vUpdates[id] = true;
617 });
618 Simulate();
619 if(fUseReo) {
620 time_point timeStart = GetCurrentTime();
621 pBdd->Reorder();
622 pBdd->TurnOffReo();
623 durationReorder += Duration(timeStart, GetCurrentTime());
624 }
625 pNtk->ForEachInt([&](int id) {
626 vvCs[id].resize(pNtk->GetNumFanins(id), LitMax);
627 });
628 pNtk->ForEachPo([&](int id) {
629 vvCs[id].resize(1, LitMax);
630 Assign(vvCs[id][0], pBdd->Const0());
631 int fi = pNtk->GetFanin(id, 0);
632 vGUpdates[fi] = true;
633 });
634 fInitialized = true;
635 }
636
637 /* }}} */
638
639 /* {{{ Save & load */
640
641 template <typename Ntk>
642 void BddMspfAnalyzer<Ntk>::Save(int slot) {
643 if(slot >= int_size(vBackups)) {
644 vBackups.resize(slot + 1);
645 }
646 CopyVec(vBackups[slot].vFs, vFs);
647 CopyVec(vBackups[slot].vGs, vGs);
648 CopyVecVec(vBackups[slot].vvCs, vvCs);
649 vBackups[slot].fUpdate = fUpdate;
650 vBackups[slot].vUpdates = vUpdates;
651 vBackups[slot].vGUpdates = vGUpdates;
652 vBackups[slot].vCUpdates = vCUpdates;
653 vBackups[slot].vVisits = vVisits;
654 }
655
656 template <typename Ntk>
657 void BddMspfAnalyzer<Ntk>::Load(int slot) {
658 assert(slot < int_size(vBackups));
659 CopyVec(vFs, vBackups[slot].vFs);
660 CopyVec(vGs, vBackups[slot].vGs);
661 CopyVecVec(vvCs, vBackups[slot].vvCs);
662 fUpdate = vBackups[slot].fUpdate;
663 vUpdates = vBackups[slot].vUpdates;
664 vGUpdates = vBackups[slot].vGUpdates;
665 vCUpdates = vBackups[slot].vCUpdates;
666 vVisits = vBackups[slot].vVisits;
667 }
668
669 template <typename Ntk>
670 void BddMspfAnalyzer<Ntk>::PopBack() {
671 assert(!vBackups.empty());
672 DelVec(vBackups.back().vFs);
673 DelVec(vBackups.back().vGs);
674 DelVecVec(vBackups.back().vvCs);
675 vBackups.pop_back();
676 }
677
678 /* }}} */
679
680 /* {{{ Constructor */
681
682 template <typename Ntk>
684 pNtk(NULL),
685 nVerbose(0),
686 fInitialized(false),
687 pBdd(NULL),
688 fUpdate(false) {
689 ResetSummary();
690 }
691
692 template <typename Ntk>
694 pNtk(NULL),
695 nVerbose(pPar->nAnalyzerVerbose),
696 fInitialized(false),
697 pBdd(NULL),
698 fUpdate(false) {
699 ResetSummary();
700 }
701
702 template <typename Ntk>
706
707 template <typename Ntk>
708 void BddMspfAnalyzer<Ntk>::AssignNetwork(Ntk *pNtk_, bool fReuse) {
709 Reset(fReuse);
710 pNtk = pNtk_;
711 pNtk->AddCallback(std::bind(&BddMspfAnalyzer<Ntk>::ActionCallback, this, std::placeholders::_1));
712 }
713
714 /* }}} */
715
716 /* {{{ Checks */
717
718 template <typename Ntk>
720 if(!fInitialized) {
721 Initialize();
722 } else if(fUpdate) {
723 Simulate();
724 fUpdate = false;
725 }
726 Mspf(id);
727 time_point timeStart = GetCurrentTime();
728 bool fRedundant = false;
729 switch(pNtk->GetNodeType(id)) {
730 case AND: {
731 int fi = pNtk->GetFanin(id, idx);
732 bool c = pNtk->GetCompl(id, idx);
733 lit x = pBdd->Or(pBdd->LitNotCond(vFs[fi], c), vvCs[id][idx]);
734 if(pBdd->IsConst1(x)) {
735 fRedundant = true;
736 }
737 break;
738 }
739 default:
740 assert(0);
741 }
742 if(nVerbose) {
743 if(fRedundant) {
744 std::cout << "node " << id << " fanin " << (pNtk->GetCompl(id, idx)? "!": "") << pNtk->GetFanin(id, idx) << " index " << idx << " is redundant" << std::endl;
745 } else {
746 std::cout << "node " << id << " fanin " << (pNtk->GetCompl(id, idx)? "!": "") << pNtk->GetFanin(id, idx) << " index " << idx << " is NOT redundant" << std::endl;
747 }
748 }
749 durationCheck += Duration(timeStart, GetCurrentTime());
750 return fRedundant;
751 }
752
753 template <typename Ntk>
754 bool BddMspfAnalyzer<Ntk>::CheckFeasibility(int id, int fi, bool c) {
755 if(!fInitialized) {
756 Initialize();
757 } else if(fUpdate) {
758 Simulate();
759 fUpdate = false;
760 }
761 Mspf(id, false);
762 time_point timeStart = GetCurrentTime();
763 bool fFeasible = false;
764 switch(pNtk->GetNodeType(id)) {
765 case AND: {
766 lit x = pBdd->Or(pBdd->LitNot(vFs[id]), vGs[id]);
767 IncRef(x);
768 lit y = pBdd->Or(x, pBdd->LitNotCond(vFs[fi], c));
769 DecRef(x);
770 if(pBdd->IsConst1(y)) {
771 fFeasible = true;
772 return true;
773 }
774 break;
775 }
776 default:
777 assert(0);
778 }
779 if(nVerbose) {
780 if(fFeasible) {
781 std::cout << "node " << id << " fanin " << (c? "!": "") << fi << " is feasible" << std::endl;
782 } else {
783 std::cout << "node " << id << " fanin " << (c? "!": "") << fi << " is NOT feasible" << std::endl;
784 }
785 }
786 durationCheck += Duration(timeStart, GetCurrentTime());
787 return fFeasible;
788 }
789
790 /* }}} */
791
792 /* {{{ Summary */
793
794 template <typename Ntk>
796 if(pBdd) {
797 nNodesOld = pBdd->GetNumTotalCreatedNodes();
798 } else {
799 nNodesOld = 0;
800 }
801 nNodesAccumulated = 0;
802 durationSimulation = 0;
803 durationPf = 0;
804 durationCheck = 0;
805 durationReorder = 0;
806 }
807
808 template <typename Ntk>
810 summary<int> v;
811 v.emplace_back("bdd node", pBdd->GetNumTotalCreatedNodes() - nNodesOld + nNodesAccumulated);
812 return v;
813 }
814
815 template <typename Ntk>
818 v.emplace_back("bdd symbolic simulation", durationSimulation);
819 v.emplace_back("bdd care computation", durationPf);
820 v.emplace_back("bdd check", durationCheck);
821 v.emplace_back("bdd reorder", durationReorder);
822 return v;
823 }
824
825 /* }}} */
826
827}
828
#define ABC_NAMESPACE_CXX_HEADER_START
#define ABC_NAMESPACE_CXX_HEADER_END
summary< double > GetTimesSummary() const
bool CheckRedundancy(int id, int idx)
bool CheckFeasibility(int id, int fi, bool c)
summary< int > GetStatsSummary() const
void AssignNetwork(Ntk *pNtk_, bool fReuse)
unsigned long long size
Definition giaNewBdd.h:39
Definition rrr.h:16
std::vector< std::pair< std::string, T > > summary
Definition rrrTypes.h:66
@ POP_BACK
Definition rrrTypes.h:45
@ REMOVE_BUFFER
Definition rrrTypes.h:36
@ REMOVE_UNUSED
Definition rrrTypes.h:35
@ TRIVIAL_DECOMPOSE
Definition rrrTypes.h:40
@ TRIVIAL_COLLAPSE
Definition rrrTypes.h:39
@ SAVE
Definition rrrTypes.h:43
@ REMOVE_CONST
Definition rrrTypes.h:37
@ LOAD
Definition rrrTypes.h:44
@ SORT_FANINS
Definition rrrTypes.h:41
@ REMOVE_FANIN
Definition rrrTypes.h:34
@ ADD_FANIN
Definition rrrTypes.h:38
@ READ
Definition rrrTypes.h:42
std::chrono::time_point< clock_type > time_point
Definition rrrTypes.h:63
@ AND
Definition rrrTypes.h:13
#define false
Definition place_base.h:29
int lit
Definition satVec.h:130
#define assert(ex)
Definition util_old.h:213