@@ -18,8 +18,7 @@ void BLIF_file::reset(CStr nm, uint16_t tr) noexcept {
18
18
topOutputs_.clear ();
19
19
fabricNodes_.clear ();
20
20
fabricRealNodes_.clear ();
21
- dang_RAM_outputs_.clear ();
22
- dang_DSP_outputs_.clear ();
21
+ dangOutputs_.clear ();
23
22
latches_.clear ();
24
23
constantNodes_.clear ();
25
24
rd_ok_ = chk_ok_ = false ;
@@ -197,6 +196,17 @@ CStr BLIF_file::BNode::cPrimType() const noexcept {
197
196
return ptype_ == prim::A_ZERO ? " {e}" : pr_enum2str (ptype_);
198
197
}
199
198
199
+ bool BLIF_file::BNode::isDanglingTerm (uint term) const noexcept {
200
+ if (dangTerms_.empty ())
201
+ return false ;
202
+ const uint* A = dangTerms_.data ();
203
+ for (int64_t i = int64_t (dangTerms_.size ()) - 1 ; i >= 0 ; i--) {
204
+ if (A[i] == term)
205
+ return true ;
206
+ }
207
+ return false ;
208
+ }
209
+
200
210
int BLIF_file::findTermByNet (const vector<string>& D, const string& net) noexcept {
201
211
assert (not net.empty ());
202
212
assert (not D.empty ());
@@ -885,9 +895,24 @@ uint BLIF_file::countConstNodes() const noexcept {
885
895
}
886
896
887
897
uint BLIF_file::numWarnings () const noexcept {
888
- assert (dang_RAM_outputs_.size () < size_t (INT_MAX));
889
- assert (dang_DSP_outputs_.size () < size_t (INT_MAX));
890
- return dang_RAM_outputs_.size () + dang_DSP_outputs_.size ();
898
+ assert (dangOutputs_.size () < size_t (INT_MAX));
899
+ return dangOutputs_.size ();
900
+ }
901
+
902
+ BLIF_file::NodeDescriptor BLIF_file::hasDanglingBit (uint lnum) const noexcept {
903
+ assert (dangOutputs_.size () < size_t (INT_MAX));
904
+ NodeDescriptor ret;
905
+ if (!lnum or dangOutputs_.empty ())
906
+ return ret;
907
+
908
+ // TMP linear
909
+ for (const NodeDescriptor& desc : dangOutputs_) {
910
+ if (desc.lnum_ == lnum) {
911
+ ret = desc;
912
+ break ;
913
+ }
914
+ }
915
+ return ret;
891
916
}
892
917
893
918
uint BLIF_file::printCarryNodes (std::ostream& os) const noexcept {
@@ -1118,8 +1143,7 @@ bool BLIF_file::createNodes() noexcept {
1118
1143
topOutputs_.clear ();
1119
1144
fabricNodes_.clear ();
1120
1145
fabricRealNodes_.clear ();
1121
- dang_RAM_outputs_.clear ();
1122
- dang_DSP_outputs_.clear ();
1146
+ dangOutputs_.clear ();
1123
1147
latches_.clear ();
1124
1148
constantNodes_.clear ();
1125
1149
if (!rd_ok_) return false ;
@@ -1173,7 +1197,7 @@ bool BLIF_file::createNodes() noexcept {
1173
1197
nodePool_.emplace_back (); // put a fake node
1174
1198
}
1175
1199
1176
- char buf[4096 ] = {};
1200
+ char buf[8192 ] = {};
1177
1201
V.clear ();
1178
1202
inputs_lnum_ = outputs_lnum_ = 0 ;
1179
1203
err_lnum_ = 0 ;
@@ -1550,8 +1574,6 @@ void BLIF_file::BNode::allInputPins(vector<string>& V) const noexcept {
1550
1574
return ;
1551
1575
}
1552
1576
1553
- // void BLIF_file::BNode:: allInputSignals(vector<string>& V) const noexcept;
1554
-
1555
1577
BLIF_file::BNode* BLIF_file::findOutputPort (const string& contact) noexcept {
1556
1578
assert (not contact.empty ());
1557
1579
if (topOutputs_.empty ()) return nullptr ;
@@ -1765,10 +1787,7 @@ bool BLIF_file::linkNodes() noexcept {
1765
1787
lputs ();
1766
1788
}
1767
1789
realNd.dangTerms_ .push_back (dataTerm);
1768
- if (nd.is_RAM ())
1769
- dang_RAM_outputs_.emplace_back (realNd.id_ , dataTerm);
1770
- else
1771
- dang_DSP_outputs_.emplace_back (realNd.id_ , dataTerm);
1790
+ dangOutputs_.emplace_back (realNd.lnum_ , realNd.id_ , dataTerm);
1772
1791
continue ;
1773
1792
}
1774
1793
err_msg_ = " dangling cell output: " ;
@@ -2228,7 +2247,7 @@ bool BLIF_file::createPinGraph() noexcept {
2228
2247
}
2229
2248
uint driver_realId = driver->realId (*this );
2230
2249
2231
- if (trace_ >= 5 ) {
2250
+ if (trace_ >= 6 ) {
2232
2251
lputs ();
2233
2252
lprintf (" from cn#%u %s " ,
2234
2253
cn_realId, cn.cPrimType () );
@@ -2503,29 +2522,99 @@ string BLIF_file::writeBlif(const string& toFn, bool cleanUp) noexcept {
2503
2522
return {};
2504
2523
}
2505
2524
2525
+ constexpr uint buf_CAP = 1048574 ; // 1 MiB
2526
+ char buf[buf_CAP + 2 ] = {};
2506
2527
size_t cnt = 0 , n = lines_.size ();
2507
- for (size_t i = 0 ; i < n; i++) {
2508
- CStr cs = lines_[i];
2509
- if (!cs || !cs[0 ]) continue ;
2510
- ::fputs (cs, f);
2528
+ if (n < 2 ) {
2529
+ ::fclose (f);
2530
+ return {};
2531
+ }
2532
+ bool error = false ;
2533
+
2534
+ ::fprintf (f, " ### written by PLN %s\n\n " , pln_get_version());
2535
+ if (::ferror (f)) {
2536
+ if (trace_ >= 3 ) {
2537
+ flush_out (true );
2538
+ lprintf (" ERROR writeBlif() error during writing: %s\n " , cnm);
2539
+ flush_out (true );
2540
+ }
2541
+ error = true ;
2542
+ n = 0 ; // skips the loop
2543
+ }
2544
+
2545
+ for (size_t lineNum = 0 ; lineNum < n; lineNum++) {
2546
+ CStr cs = lines_[lineNum];
2547
+ if (!cs || !cs[0 ])
2548
+ continue ;
2549
+
2550
+ ::strncpy (buf, cs, buf_CAP);
2551
+
2552
+ if (cleanUp) {
2553
+ NodeDescriptor ddesc = hasDanglingBit (lineNum);
2554
+ if (ddesc.valid ()) {
2555
+ assert (ddesc.nid_ > 0 );
2556
+ const BNode& dNode = bnodeRef (ddesc.nid_ );
2557
+ assert (not dNode.isVirtualMog ());
2558
+ assert (not dNode.realData_ .empty ());
2559
+ assert (not dNode.dangTerms_ .empty ());
2560
+ // build 'buf' skipping dangling terms
2561
+ uint skipCnt = 0 ;
2562
+ buf[0 ] = 0 ; buf[1 ] = 0 ;
2563
+ size_t rdsz = dNode.realData_ .size ();
2564
+ if (trace_ >= 4 ) {
2565
+ lprintf (" wrBlif: cell %s at line %zu has dangling bit, filtering..\n " ,
2566
+ dNode.cPrimType (), lineNum);
2567
+ if (trace_ >= 5 ) {
2568
+ lprintf (" dangling cell realData_.size()= %zu\n " , rdsz);
2569
+ }
2570
+ }
2571
+ char * tail = ::stpcpy (buf, " .subckt" );
2572
+ for (size_t i = 0 ; i < rdsz; i++) {
2573
+ if (dNode.isDanglingTerm (i)) {
2574
+ if (trace_ >= 6 )
2575
+ lprintf (" \t (wrBlif) skipping dangling term %zu\n " , i);
2576
+ skipCnt++;
2577
+ continue ;
2578
+ }
2579
+ CStr ts = dNode.realData_ [i].c_str ();
2580
+ tail = ::stpcpy (tail, " " );
2581
+ tail = ::stpcpy (tail, ts);
2582
+ }
2583
+ if (trace_ >= 4 ) {
2584
+ lprintf (" wrBlif: filtered dangling bits (%u) for cell %s at line %zu\n " ,
2585
+ skipCnt, dNode.cPrimType (), lineNum);
2586
+ }
2587
+ }
2588
+ }
2589
+
2590
+ ::fputs (buf, f);
2511
2591
::fputc (' \n ' , f);
2592
+
2512
2593
if (::ferror (f)) {
2513
2594
if (trace_ >= 3 ) {
2514
2595
flush_out (true );
2515
2596
lprintf (" ERROR writeBlif() error during writing: %s\n " , cnm);
2516
2597
flush_out (true );
2517
2598
}
2599
+ error = true ;
2518
2600
break ;
2519
2601
}
2520
2602
cnt++;
2521
2603
}
2522
2604
2523
2605
::fclose (f);
2524
2606
2525
- if (trace_ >= 4 ) {
2526
- flush_out (trace_ >= 5 );
2607
+ flush_out (trace_ >= 5 );
2608
+
2609
+ if (error) {
2610
+ flush_out (true ); err_puts ();
2611
+ lprintf2 (" [Error] writeBlif ERROR writing: %s\n " , cnm);
2612
+ err_puts (); flush_out (true );
2613
+ }
2614
+ else if (trace_ >= 4 ) {
2527
2615
lprintf (" writeBlif OK written #lines= %zu\n " , cnt);
2528
2616
}
2617
+
2529
2618
flush_out (trace_ >= 5 );
2530
2619
2531
2620
return fn2;
0 commit comments