@@ -1199,12 +1199,6 @@ bool BLIF_file::createNodes() noexcept {
11991199 if (not starts_w_subckt (cs + 1 , len - 1 ))
12001200 continue ;
12011201 Fio::split_spa (lines_[L], V);
1202- // if (L == 48) {
1203- // string delWire1151 = "$delete_wire$1151";
1204- // lputs8();
1205- // int dTerm = findTermByNet(V, delWire1151);
1206- // lprintf(" dTerm= %i\n", dTerm);
1207- // }
12081202 if (V.size () > 1 and V.front () == " .subckt" ) {
12091203 Prim_t pt = pr_str2enum ( V[1 ].c_str () );
12101204 if (pr_is_MOG (pt)) {
@@ -1997,7 +1991,35 @@ bool BLIF_file::checkClockSepar(vector<BNode*>& clocked) noexcept {
19971991 }
19981992 }
19991993
2000- if (trace_ >= 6 ) {
1994+ // -- paint top-output nodes (and their incoming wires) Black
1995+ for (BNode* p : topOutputs_) {
1996+ const BNode& port = *p;
1997+ assert (!port.out_ .empty ());
1998+ assert (port.nw_id_ );
1999+ if (!port.nw_id_ )
2000+ continue ;
2001+ NW::Node& nd = pg_.nodeRefCk (port.nw_id_ );
2002+ nd.paintBlack ();
2003+ uint par = port.parent_ ;
2004+ while (par) {
2005+ const BNode& parBn = bnodeRef (par);
2006+ assert (parBn.nw_id_ );
2007+ if (!parBn.nw_id_ )
2008+ break ;
2009+ if (!parBn.is_WIRE ())
2010+ break ;
2011+ NW::Node& nwn = pg_.nodeRefCk (parBn.nw_id_ );
2012+ nwn.paintBlack ();
2013+ if (nwn.parent ()) {
2014+ NW::Node& nwp = pg_.nodeRefCk (nwn.parent ());
2015+ if (map_pg2blif (nwp.id_ ) == parBn.id_ )
2016+ nwp.paintBlack ();
2017+ }
2018+ par = parBn.parent_ ;
2019+ }
2020+ }
2021+
2022+ if (trace_ >= 5 ) {
20012023 lputs (" (Pin Graph) *** summary after B ***" );
20022024 pg_.printSum (ls, 0 );
20032025 lputs ();
@@ -2025,13 +2047,16 @@ bool BLIF_file::checkClockSepar(vector<BNode*>& clocked) noexcept {
20252047 bool color_ok = true ;
20262048 CStr viol_prefix = " [Error] clock-data separation ERROR" ;
20272049
2028- // -- check that end-points of red edges are red
2050+ // -- check that end-points of red edges are red,
2051+ // the destination node may be black (output port)
20292052 for (NW::cEI E (pg_); E.valid (); ++E) {
20302053 const NW::Edge& ed = *E;
20312054 if (not ed.isRed ())
20322055 continue ;
20332056 NW::Node& p1 = pg_.nodeRef (ed.n1_ );
20342057 NW::Node& p2 = pg_.nodeRef (ed.n2_ );
2058+ if (p2.isBlack ())
2059+ continue ;
20352060 if (!p1.isRed () or !p2.isRed ()) {
20362061 color_ok = false ;
20372062 p1.markViol (true );
@@ -2170,50 +2195,57 @@ bool BLIF_file::createPinGraph() noexcept {
21702195
21712196 // -- link in-ports to out-ports via feedthrough wires
21722197 for (BNode* x : fabricRealNodes_) {
2173- if (x->is_WIRE ()) {
2174- BNode& w = *x;
2175- assert (w.data_ .size () == 2 );
2176- const string& w_inp = w.data_ .front ();
2177- const string& w_out = w.data_ .back ();
2178- BNode* iport = findInputPort (w_inp);
2179- if (!iport)
2180- continue ;
2181- BNode* oport = findOutputPort (w_out);
2182- if (!oport)
2183- continue ;
2184- assert (iport->isTopInput ());
2185- assert (oport->isTopOutput ());
2186- // NW-nodes for i/o ports should exist already
2187- assert (iport->nw_id_ );
2188- assert (oport->nw_id_ );
2189- assert (pg_.hasNode (iport->nw_id_ ));
2190- assert (pg_.hasNode (oport->nw_id_ ));
2191- assert (map_pg2blif (iport->nw_id_ ) == iport->id_ );
2192- assert (map_pg2blif (oport->nw_id_ ) == oport->id_ );
2193-
2194- // NW keys and nodes for wire pseudo-cell:
2195- uint64_t w_k1 = hashCantor (w.id_ , 1 ) + max_key1;
2196- uint64_t w_k2 = hashCantor (w.id_ , 2 ) + max_key1;
2197- assert (w_k1);
2198- assert (w_k2);
2199- assert (w_k1 != w_k2);
2200- uint w_n1 = pg_.insK (w_k1);
2201- assert (w_n1);
2202- uint w_n2 = pg_.insK (w_k2);
2203- assert (w_n2);
2204- pg2blif_.emplace (w_n1, w.id_ );
2205- pg2blif_.emplace (w_n2, w.id_ );
2206- pg_.setNodeName4 (w_n1, w.id_ , w.lnum_ , 1 , " FTwireI" );
2207- pg_.setNodeName4 (w_n2, w.id_ , w.lnum_ , 2 , " FTwireO" );
2208-
2209- // link feedthrough:
2210- uint ee;
2211- ee = pg_.linkNodes (iport->nw_id_ , w_n1, false );
2212- ee = pg_.linkNodes (w_n1, w_n2, true );
2213- ee = pg_.linkNodes (w_n2, oport->nw_id_ , false );
2214- if (trace_ >= 11 )
2215- lprintf (" \t\t ee = %u\n " , ee);
2216- }
2198+ BNode& w = *x;
2199+ if (not w.is_WIRE ())
2200+ continue ;
2201+ assert (w.data_ .size () == 2 );
2202+ const string& w_inp = w.data_ .front ();
2203+ const string& w_out = w.data_ .back ();
2204+ BNode* iport = findInputPort (w_inp);
2205+ if (!iport)
2206+ continue ;
2207+ BNode* oport = findOutputPort (w_out);
2208+ if (!oport)
2209+ continue ;
2210+ assert (iport->isTopInput ());
2211+ assert (oport->isTopOutput ());
2212+ // NW-nodes for i/o ports should exist already
2213+ assert (iport->nw_id_ );
2214+ assert (oport->nw_id_ );
2215+ assert (pg_.hasNode (iport->nw_id_ ));
2216+ assert (pg_.hasNode (oport->nw_id_ ));
2217+ assert (map_pg2blif (iport->nw_id_ ) == iport->id_ );
2218+ assert (map_pg2blif (oport->nw_id_ ) == oport->id_ );
2219+
2220+ // NW keys and nodes for wire pseudo-cell:
2221+ uint64_t w_k1 = hashCantor (w.id_ , 1 ) + max_key1;
2222+ uint64_t w_k2 = hashCantor (w.id_ , 2 ) + max_key1;
2223+ assert (w_k1);
2224+ assert (w_k2);
2225+ assert (w_k1 != w_k2);
2226+ uint w_n1 = pg_.insK (w_k1);
2227+ assert (w_n1);
2228+ uint w_n2 = pg_.insK (w_k2);
2229+ assert (w_n2);
2230+ pg2blif_.emplace (w_n1, w.id_ );
2231+ pg2blif_.emplace (w_n2, w.id_ );
2232+ w.nw_id_ = w_n2;
2233+ pg_.nodeRef (w_n1).markWire (true );
2234+ pg_.nodeRef (w_n2).markWire (true );
2235+ pg_.setNodeName4 (w_n1, w.id_ , w.lnum_ , 1 , " FTwireI" );
2236+ pg_.setNodeName4 (w_n2, w.id_ , w.lnum_ , 2 , " FTwireO" );
2237+
2238+ // make sure BNode::parent_ links are set
2239+ oport->parent_ = w.id_ ;
2240+ w.parent_ = iport->id_ ;
2241+
2242+ // link feedthrough:
2243+ uint ee;
2244+ ee = pg_.linkNodes (iport->nw_id_ , w_n1, false );
2245+ ee = pg_.linkNodes (w_n1, w_n2, true );
2246+ ee = pg_.linkNodes (w_n2, oport->nw_id_ , false );
2247+ if (trace_ >= 11 )
2248+ lprintf (" \t\t ee = %u\n " , ee);
22172249 }
22182250
22192251 // -- link from input ports to fabric
0 commit comments