@@ -18,8 +18,7 @@ void BLIF_file::reset(CStr nm, uint16_t tr) noexcept {
1818 topOutputs_.clear ();
1919 fabricNodes_.clear ();
2020 fabricRealNodes_.clear ();
21- dang_RAM_outputs_.clear ();
22- dang_DSP_outputs_.clear ();
21+ dangOutputs_.clear ();
2322 latches_.clear ();
2423 constantNodes_.clear ();
2524 rd_ok_ = chk_ok_ = false ;
@@ -197,6 +196,17 @@ CStr BLIF_file::BNode::cPrimType() const noexcept {
197196 return ptype_ == prim::A_ZERO ? " {e}" : pr_enum2str (ptype_);
198197}
199198
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+
200210int BLIF_file::findTermByNet (const vector<string>& D, const string& net) noexcept {
201211 assert (not net.empty ());
202212 assert (not D.empty ());
@@ -885,9 +895,24 @@ uint BLIF_file::countConstNodes() const noexcept {
885895}
886896
887897uint 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;
891916}
892917
893918uint BLIF_file::printCarryNodes (std::ostream& os) const noexcept {
@@ -1118,8 +1143,7 @@ bool BLIF_file::createNodes() noexcept {
11181143 topOutputs_.clear ();
11191144 fabricNodes_.clear ();
11201145 fabricRealNodes_.clear ();
1121- dang_RAM_outputs_.clear ();
1122- dang_DSP_outputs_.clear ();
1146+ dangOutputs_.clear ();
11231147 latches_.clear ();
11241148 constantNodes_.clear ();
11251149 if (!rd_ok_) return false ;
@@ -1173,7 +1197,7 @@ bool BLIF_file::createNodes() noexcept {
11731197 nodePool_.emplace_back (); // put a fake node
11741198 }
11751199
1176- char buf[4096 ] = {};
1200+ char buf[8192 ] = {};
11771201 V.clear ();
11781202 inputs_lnum_ = outputs_lnum_ = 0 ;
11791203 err_lnum_ = 0 ;
@@ -1550,8 +1574,6 @@ void BLIF_file::BNode::allInputPins(vector<string>& V) const noexcept {
15501574 return ;
15511575}
15521576
1553- // void BLIF_file::BNode:: allInputSignals(vector<string>& V) const noexcept;
1554-
15551577BLIF_file::BNode* BLIF_file::findOutputPort (const string& contact) noexcept {
15561578 assert (not contact.empty ());
15571579 if (topOutputs_.empty ()) return nullptr ;
@@ -1765,10 +1787,7 @@ bool BLIF_file::linkNodes() noexcept {
17651787 lputs ();
17661788 }
17671789 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);
17721791 continue ;
17731792 }
17741793 err_msg_ = " dangling cell output: " ;
@@ -2228,7 +2247,7 @@ bool BLIF_file::createPinGraph() noexcept {
22282247 }
22292248 uint driver_realId = driver->realId (*this );
22302249
2231- if (trace_ >= 5 ) {
2250+ if (trace_ >= 6 ) {
22322251 lputs ();
22332252 lprintf (" from cn#%u %s " ,
22342253 cn_realId, cn.cPrimType () );
@@ -2503,29 +2522,99 @@ string BLIF_file::writeBlif(const string& toFn, bool cleanUp) noexcept {
25032522 return {};
25042523 }
25052524
2525+ constexpr uint buf_CAP = 1048574 ; // 1 MiB
2526+ char buf[buf_CAP + 2 ] = {};
25062527 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);
25112591 ::fputc (' \n ' , f);
2592+
25122593 if (::ferror (f)) {
25132594 if (trace_ >= 3 ) {
25142595 flush_out (true );
25152596 lprintf (" ERROR writeBlif() error during writing: %s\n " , cnm);
25162597 flush_out (true );
25172598 }
2599+ error = true ;
25182600 break ;
25192601 }
25202602 cnt++;
25212603 }
25222604
25232605 ::fclose (f);
25242606
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 ) {
25272615 lprintf (" writeBlif OK written #lines= %zu\n " , cnt);
25282616 }
2617+
25292618 flush_out (trace_ >= 5 );
25302619
25312620 return fn2;
0 commit comments