1 /**CFile****************************************************************
2 
3   FileName    [ioWriteBlif.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Command processing package.]
8 
9   Synopsis    [Procedures to write BLIF files.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - June 20, 2005.]
16 
17   Revision    [$Id: ioWriteBlif.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "ioAbc.h"
22 #include "base/main/main.h"
23 #include "map/mio/mio.h"
24 #include "bool/kit/kit.h"
25 #include "map/if/if.h"
26 
27 ABC_NAMESPACE_IMPL_START
28 
29 
30 ////////////////////////////////////////////////////////////////////////
31 ///                        DECLARATIONS                              ///
32 ////////////////////////////////////////////////////////////////////////
33 
34 static void Io_NtkWrite( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches, int fBb2Wb, int fSeq );
35 static void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches, int fBb2Wb, int fSeq );
36 static void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
37 static void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
38 static void Io_NtkWriteSubckt( FILE * pFile, Abc_Obj_t * pNode );
39 static void Io_NtkWriteAsserts( FILE * pFile, Abc_Ntk_t * pNtk );
40 static void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode );
41 static int  Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode, int Length );
42 static void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch );
43 
44 ////////////////////////////////////////////////////////////////////////
45 ///                     FUNCTION DEFINITIONS                         ///
46 ////////////////////////////////////////////////////////////////////////
47 
48 /**Function*************************************************************
49 
50   Synopsis    [Write the network into a BLIF file with the given name.]
51 
52   Description []
53 
54   SideEffects []
55 
56   SeeAlso     []
57 
58 ***********************************************************************/
Io_WriteBlifLogic(Abc_Ntk_t * pNtk,char * FileName,int fWriteLatches)59 void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
60 {
61     Abc_Ntk_t * pNtkTemp;
62     // derive the netlist
63     pNtkTemp = Abc_NtkToNetlist(pNtk);
64     if ( pNtkTemp == NULL )
65     {
66         fprintf( stdout, "Writing BLIF has failed.\n" );
67         return;
68     }
69     Io_WriteBlif( pNtkTemp, FileName, fWriteLatches, 0, 0 );
70     Abc_NtkDelete( pNtkTemp );
71 }
72 
73 /**Function*************************************************************
74 
75   Synopsis    [Write the network into a BLIF file with the given name.]
76 
77   Description []
78 
79   SideEffects []
80 
81   SeeAlso     []
82 
83 ***********************************************************************/
Io_WriteBlif(Abc_Ntk_t * pNtk,char * FileName,int fWriteLatches,int fBb2Wb,int fSeq)84 void Io_WriteBlif( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches, int fBb2Wb, int fSeq )
85 {
86     FILE * pFile;
87     Abc_Ntk_t * pNtkTemp;
88     int i;
89     assert( Abc_NtkIsNetlist(pNtk) );
90     // start writing the file
91     pFile = fopen( FileName, "w" );
92     if ( pFile == NULL )
93     {
94         fprintf( stdout, "Io_WriteBlif(): Cannot open the output file.\n" );
95         return;
96     }
97     fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
98     // write the master network
99     Io_NtkWrite( pFile, pNtk, fWriteLatches, fBb2Wb, fSeq );
100     // make sure there is no logic hierarchy
101 //    assert( Abc_NtkWhiteboxNum(pNtk) == 0 );
102     // write the hierarchy if present
103     if ( Abc_NtkBlackboxNum(pNtk) > 0 || Abc_NtkWhiteboxNum(pNtk) > 0 )
104     {
105         Vec_PtrForEachEntry( Abc_Ntk_t *, pNtk->pDesign->vModules, pNtkTemp, i )
106         {
107             if ( pNtkTemp == pNtk )
108                 continue;
109             fprintf( pFile, "\n\n" );
110             Io_NtkWrite( pFile, pNtkTemp, fWriteLatches, fBb2Wb, fSeq );
111         }
112     }
113     fclose( pFile );
114 }
115 
116 /**Function*************************************************************
117 
118   Synopsis    [Write the network into a BLIF file with the given name.]
119 
120   Description []
121 
122   SideEffects []
123 
124   SeeAlso     []
125 
126 ***********************************************************************/
Io_NtkWrite(FILE * pFile,Abc_Ntk_t * pNtk,int fWriteLatches,int fBb2Wb,int fSeq)127 void Io_NtkWrite( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches, int fBb2Wb, int fSeq )
128 {
129     Abc_Ntk_t * pExdc;
130     assert( Abc_NtkIsNetlist(pNtk) );
131     // write the model name
132     fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) );
133     // write the network
134     Io_NtkWriteOne( pFile, pNtk, fWriteLatches, fBb2Wb, fSeq );
135     // write EXDC network if it exists
136     pExdc = Abc_NtkExdc( pNtk );
137     if ( pExdc )
138     {
139         fprintf( pFile, "\n" );
140         fprintf( pFile, ".exdc\n" );
141         Io_NtkWriteOne( pFile, pExdc, fWriteLatches, fBb2Wb, fSeq );
142     }
143     // finalize the file
144     fprintf( pFile, ".end\n" );
145 }
146 
147 /**Function*************************************************************
148 
149   Synopsis    [Write one network.]
150 
151   Description []
152 
153   SideEffects []
154 
155   SeeAlso     []
156 
157 ***********************************************************************/
Io_NtkWriteConvertedBox(FILE * pFile,Abc_Ntk_t * pNtk,int fSeq)158 void Io_NtkWriteConvertedBox( FILE * pFile, Abc_Ntk_t * pNtk, int fSeq )
159 {
160     Abc_Obj_t * pObj;
161     int i, v;
162     if ( fSeq )
163     {
164         fprintf( pFile, ".attrib white box seq\n" );
165     }
166     else
167     {
168         fprintf( pFile, ".attrib white box comb\n" );
169         fprintf( pFile, ".delay 1\n" );
170     }
171     Abc_NtkForEachPo( pNtk, pObj, i )
172     {
173         // write the .names line
174         fprintf( pFile, ".names" );
175         Io_NtkWritePis( pFile, pNtk, 1 );
176         if ( fSeq )
177             fprintf( pFile, " %s_in\n", Abc_ObjName(Abc_ObjFanin0(pObj)) );
178         else
179             fprintf( pFile, " %s\n", Abc_ObjName(Abc_ObjFanin0(pObj)) );
180         for ( v = 0; v < Abc_NtkPiNum(pNtk); v++ )
181             fprintf( pFile, "1" );
182         fprintf( pFile, " 1\n" );
183         if ( fSeq )
184             fprintf( pFile, ".latch %s_in %s 1\n", Abc_ObjName(Abc_ObjFanin0(pObj)), Abc_ObjName(Abc_ObjFanin0(pObj)) );
185     }
186 }
187 
188 /**Function*************************************************************
189 
190   Synopsis    [Write one network.]
191 
192   Description []
193 
194   SideEffects []
195 
196   SeeAlso     []
197 
198 ***********************************************************************/
Io_NtkWriteOne(FILE * pFile,Abc_Ntk_t * pNtk,int fWriteLatches,int fBb2Wb,int fSeq)199 void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches, int fBb2Wb, int fSeq )
200 {
201     ProgressBar * pProgress;
202     Abc_Obj_t * pNode, * pLatch;
203     int i, Length;
204 
205     // write the PIs
206     fprintf( pFile, ".inputs" );
207     Io_NtkWritePis( pFile, pNtk, fWriteLatches );
208     fprintf( pFile, "\n" );
209 
210     // write the POs
211     fprintf( pFile, ".outputs" );
212     Io_NtkWritePos( pFile, pNtk, fWriteLatches );
213     fprintf( pFile, "\n" );
214 
215     // write the blackbox
216     if ( Abc_NtkHasBlackbox( pNtk ) )
217     {
218         if ( fBb2Wb )
219             Io_NtkWriteConvertedBox( pFile, pNtk, fSeq );
220         else
221             fprintf( pFile, ".blackbox\n" );
222         return;
223     }
224 
225     // write the timing info
226     Io_WriteTimingInfo( pFile, pNtk );
227 
228     // write the latches
229     if ( fWriteLatches && !Abc_NtkIsComb(pNtk) )
230     {
231         fprintf( pFile, "\n" );
232         Abc_NtkForEachLatch( pNtk, pLatch, i )
233             Io_NtkWriteLatch( pFile, pLatch );
234         fprintf( pFile, "\n" );
235     }
236 
237     // write the subcircuits
238 //    assert( Abc_NtkWhiteboxNum(pNtk) == 0 );
239     if ( Abc_NtkBlackboxNum(pNtk) > 0 || Abc_NtkWhiteboxNum(pNtk) > 0 )
240     {
241         fprintf( pFile, "\n" );
242         Abc_NtkForEachBlackbox( pNtk, pNode, i )
243             Io_NtkWriteSubckt( pFile, pNode );
244         fprintf( pFile, "\n" );
245         Abc_NtkForEachWhitebox( pNtk, pNode, i )
246             Io_NtkWriteSubckt( pFile, pNode );
247         fprintf( pFile, "\n" );
248     }
249 
250     // write each internal node
251     Length = Abc_NtkHasMapping(pNtk)? Mio_LibraryReadGateNameMax((Mio_Library_t *)pNtk->pManFunc) : 0;
252     pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
253     Abc_NtkForEachNode( pNtk, pNode, i )
254     {
255         Extra_ProgressBarUpdate( pProgress, i, NULL );
256         if ( Io_NtkWriteNode( pFile, pNode, Length ) ) // skip the next node
257             i++;
258     }
259     Extra_ProgressBarStop( pProgress );
260 }
261 
262 
263 /**Function*************************************************************
264 
265   Synopsis    [Writes the primary input list.]
266 
267   Description []
268 
269   SideEffects []
270 
271   SeeAlso     []
272 
273 ***********************************************************************/
Io_NtkWritePis(FILE * pFile,Abc_Ntk_t * pNtk,int fWriteLatches)274 void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
275 {
276     Abc_Obj_t * pTerm, * pNet;
277     int LineLength;
278     int AddedLength;
279     int NameCounter;
280     int i;
281 
282     LineLength  = 7;
283     NameCounter = 0;
284 
285     if ( fWriteLatches )
286     {
287         Abc_NtkForEachPi( pNtk, pTerm, i )
288         {
289             pNet = Abc_ObjFanout0(pTerm);
290             // get the line length after this name is written
291             AddedLength = strlen(Abc_ObjName(pNet)) + 1;
292             if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
293             { // write the line extender
294                 fprintf( pFile, " \\\n" );
295                 // reset the line length
296                 LineLength  = 0;
297                 NameCounter = 0;
298             }
299             fprintf( pFile, " %s", Abc_ObjName(pNet) );
300             LineLength += AddedLength;
301             NameCounter++;
302         }
303     }
304     else
305     {
306         Abc_NtkForEachCi( pNtk, pTerm, i )
307         {
308             pNet = Abc_ObjFanout0(pTerm);
309             // get the line length after this name is written
310             AddedLength = strlen(Abc_ObjName(pNet)) + 1;
311             if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
312             { // write the line extender
313                 fprintf( pFile, " \\\n" );
314                 // reset the line length
315                 LineLength  = 0;
316                 NameCounter = 0;
317             }
318             fprintf( pFile, " %s", Abc_ObjName(pNet) );
319             LineLength += AddedLength;
320             NameCounter++;
321         }
322     }
323 }
324 
325 /**Function*************************************************************
326 
327   Synopsis    [Writes the primary input list.]
328 
329   Description []
330 
331   SideEffects []
332 
333   SeeAlso     []
334 
335 ***********************************************************************/
Io_NtkWritePos(FILE * pFile,Abc_Ntk_t * pNtk,int fWriteLatches)336 void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
337 {
338     Abc_Obj_t * pTerm, * pNet;
339     int LineLength;
340     int AddedLength;
341     int NameCounter;
342     int i;
343 
344     LineLength  = 8;
345     NameCounter = 0;
346 
347     if ( fWriteLatches )
348     {
349         Abc_NtkForEachPo( pNtk, pTerm, i )
350         {
351             pNet = Abc_ObjFanin0(pTerm);
352             // get the line length after this name is written
353             AddedLength = strlen(Abc_ObjName(pNet)) + 1;
354             if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
355             { // write the line extender
356                 fprintf( pFile, " \\\n" );
357                 // reset the line length
358                 LineLength  = 0;
359                 NameCounter = 0;
360             }
361             fprintf( pFile, " %s", Abc_ObjName(pNet) );
362             LineLength += AddedLength;
363             NameCounter++;
364         }
365     }
366     else
367     {
368         Abc_NtkForEachCo( pNtk, pTerm, i )
369         {
370             pNet = Abc_ObjFanin0(pTerm);
371             // get the line length after this name is written
372             AddedLength = strlen(Abc_ObjName(pNet)) + 1;
373             if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
374             { // write the line extender
375                 fprintf( pFile, " \\\n" );
376                 // reset the line length
377                 LineLength  = 0;
378                 NameCounter = 0;
379             }
380             fprintf( pFile, " %s", Abc_ObjName(pNet) );
381             LineLength += AddedLength;
382             NameCounter++;
383         }
384     }
385 }
386 
387 /**Function*************************************************************
388 
389   Synopsis    [Write the latch into a file.]
390 
391   Description []
392 
393   SideEffects []
394 
395   SeeAlso     []
396 
397 ***********************************************************************/
Io_NtkWriteSubckt(FILE * pFile,Abc_Obj_t * pNode)398 void Io_NtkWriteSubckt( FILE * pFile, Abc_Obj_t * pNode )
399 {
400     Abc_Ntk_t * pModel = (Abc_Ntk_t *)pNode->pData;
401     Abc_Obj_t * pTerm;
402     int i;
403     // write the subcircuit
404 //    fprintf( pFile, ".subckt %s %s", Abc_NtkName(pModel), Abc_ObjName(pNode) );
405     fprintf( pFile, ".subckt %s", Abc_NtkName(pModel) );
406     // write pairs of the formal=actual names
407     Abc_NtkForEachPi( pModel, pTerm, i )
408     {
409         fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanout0(pTerm)) );
410         pTerm = Abc_ObjFanin( pNode, i );
411         fprintf( pFile, "=%s", Abc_ObjName(Abc_ObjFanin0(pTerm)) );
412     }
413     Abc_NtkForEachPo( pModel, pTerm, i )
414     {
415         fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin0(pTerm)) );
416         pTerm = Abc_ObjFanout( pNode, i );
417         fprintf( pFile, "=%s", Abc_ObjName(Abc_ObjFanout0(pTerm)) );
418     }
419     fprintf( pFile, "\n" );
420 }
421 
422 /**Function*************************************************************
423 
424   Synopsis    [Write the latch into a file.]
425 
426   Description []
427 
428   SideEffects []
429 
430   SeeAlso     []
431 
432 ***********************************************************************/
Io_NtkWriteLatch(FILE * pFile,Abc_Obj_t * pLatch)433 void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch )
434 {
435     Abc_Obj_t * pNetLi, * pNetLo;
436     int Reset;
437     pNetLi = Abc_ObjFanin0( Abc_ObjFanin0(pLatch) );
438     pNetLo = Abc_ObjFanout0( Abc_ObjFanout0(pLatch) );
439     Reset  = (int)(ABC_PTRUINT_T)Abc_ObjData( pLatch );
440     // write the latch line
441     fprintf( pFile, ".latch" );
442     fprintf( pFile, " %10s",    Abc_ObjName(pNetLi) );
443     fprintf( pFile, " %10s",    Abc_ObjName(pNetLo) );
444     fprintf( pFile, "  %d\n",   Reset-1 );
445 }
446 
447 
448 /**Function*************************************************************
449 
450   Synopsis    [Writes the primary input list.]
451 
452   Description []
453 
454   SideEffects []
455 
456   SeeAlso     []
457 
458 ***********************************************************************/
Io_NtkWriteNodeFanins(FILE * pFile,Abc_Obj_t * pNode)459 void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode )
460 {
461     Abc_Obj_t * pNet;
462     int LineLength;
463     int AddedLength;
464     int NameCounter;
465     char * pName;
466     int i;
467 
468     LineLength  = 6;
469     NameCounter = 0;
470     Abc_ObjForEachFanin( pNode, pNet, i )
471     {
472         // get the fanin name
473         pName = Abc_ObjName(pNet);
474         // get the line length after the fanin name is written
475         AddedLength = strlen(pName) + 1;
476         if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
477         { // write the line extender
478             fprintf( pFile, " \\\n" );
479             // reset the line length
480             LineLength  = 0;
481             NameCounter = 0;
482         }
483         fprintf( pFile, " %s", pName );
484         LineLength += AddedLength;
485         NameCounter++;
486     }
487 
488     // get the output name
489     pName = Abc_ObjName(Abc_ObjFanout0(pNode));
490     // get the line length after the output name is written
491     AddedLength = strlen(pName) + 1;
492     if ( NameCounter && LineLength + AddedLength > 75 )
493     { // write the line extender
494         fprintf( pFile, " \\\n" );
495         // reset the line length
496         LineLength  = 0;
497         NameCounter = 0;
498     }
499     fprintf( pFile, " %s", pName );
500 }
501 
502 /**Function*************************************************************
503 
504   Synopsis    [Writes the primary input list.]
505 
506   Description []
507 
508   SideEffects []
509 
510   SeeAlso     []
511 
512 ***********************************************************************/
Io_NtkWriteSubcktFanins(FILE * pFile,Abc_Obj_t * pNode)513 void Io_NtkWriteSubcktFanins( FILE * pFile, Abc_Obj_t * pNode )
514 {
515     Abc_Obj_t * pNet;
516     int LineLength;
517     int AddedLength;
518     int NameCounter;
519     char * pName;
520     int i;
521 
522     LineLength  = 6;
523     NameCounter = 0;
524 
525     // get the output name
526     pName = Abc_ObjName(Abc_ObjFanout0(pNode));
527     // get the line length after the output name is written
528     AddedLength = strlen(pName) + 1;
529     fprintf( pFile, " m%d", Abc_ObjId(pNode) );
530 
531     // get the input names
532     Abc_ObjForEachFanin( pNode, pNet, i )
533     {
534         // get the fanin name
535         pName = Abc_ObjName(pNet);
536         // get the line length after the fanin name is written
537         AddedLength = strlen(pName) + 3;
538         if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
539         { // write the line extender
540             fprintf( pFile, " \\\n" );
541             // reset the line length
542             LineLength  = 0;
543             NameCounter = 0;
544         }
545         fprintf( pFile, " %c=%s", 'a'+i, pName );
546         LineLength += AddedLength;
547         NameCounter++;
548     }
549 
550     // get the output name
551     pName = Abc_ObjName(Abc_ObjFanout0(pNode));
552     // get the line length after the output name is written
553     AddedLength = strlen(pName) + 3;
554     if ( NameCounter && LineLength + AddedLength > 75 )
555     { // write the line extender
556         fprintf( pFile, " \\\n" );
557         // reset the line length
558         LineLength  = 0;
559         NameCounter = 0;
560     }
561     fprintf( pFile, " %c=%s", 'o', pName );
562 }
563 
564 
565 /**Function*************************************************************
566 
567   Synopsis    [Writes the primary input list.]
568 
569   Description []
570 
571   SideEffects []
572 
573   SeeAlso     []
574 
575 ***********************************************************************/
Io_NtkWriteNodeGate(FILE * pFile,Abc_Obj_t * pNode,int Length)576 int Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length )
577 {
578     static int fReport = 0;
579     Mio_Gate_t * pGate = (Mio_Gate_t *)pNode->pData;
580     Mio_Pin_t * pGatePin;
581     Abc_Obj_t * pNode2;
582     int i;
583     fprintf( pFile, " %-*s ", Length, Mio_GateReadName(pGate) );
584     for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ )
585         fprintf( pFile, "%s=%s ", Mio_PinReadName(pGatePin), Abc_ObjName( Abc_ObjFanin(pNode,i) ) );
586     assert ( i == Abc_ObjFaninNum(pNode) );
587     fprintf( pFile, "%s=%s", Mio_GateReadOutName(pGate), Abc_ObjName( Abc_ObjFanout0(pNode) ) );
588     if ( Mio_GateReadTwin(pGate) == NULL )
589         return 0;
590     pNode2 = Abc_NtkFetchTwinNode( pNode );
591     if ( pNode2 == NULL )
592     {
593         if ( !fReport )
594             fReport = 1, printf( "Warning: Missing second output of gate(s) \"%s\".\n", Mio_GateReadName(pGate) );
595         return 0;
596     }
597     fprintf( pFile, " %s=%s", Mio_GateReadOutName((Mio_Gate_t *)pNode2->pData), Abc_ObjName( Abc_ObjFanout0(pNode2) ) );
598     return 1;
599 }
600 
601 /**Function*************************************************************
602 
603   Synopsis    [Write the node into a file.]
604 
605   Description []
606 
607   SideEffects []
608 
609   SeeAlso     []
610 
611 ***********************************************************************/
Io_NtkWriteNode(FILE * pFile,Abc_Obj_t * pNode,int Length)612 int Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode, int Length )
613 {
614     int RetValue = 0;
615     if ( Abc_NtkHasMapping(pNode->pNtk) )
616     {
617         // write the .gate line
618         if ( Abc_ObjIsBarBuf(pNode) )
619         {
620             fprintf( pFile, ".barbuf " );
621             fprintf( pFile, "%s %s", Abc_ObjName(Abc_ObjFanin0(pNode)), Abc_ObjName(Abc_ObjFanout0(pNode)) );
622             fprintf( pFile, "\n" );
623         }
624         else
625         {
626             fprintf( pFile, ".gate" );
627             RetValue = Io_NtkWriteNodeGate( pFile, pNode, Length );
628             fprintf( pFile, "\n" );
629         }
630     }
631     else
632     {
633         // write the .names line
634         fprintf( pFile, ".names" );
635         Io_NtkWriteNodeFanins( pFile, pNode );
636         fprintf( pFile, "\n" );
637         // write the cubes
638         fprintf( pFile, "%s", (char*)Abc_ObjData(pNode) );
639     }
640     return RetValue;
641 }
642 
643 /**Function*************************************************************
644 
645   Synopsis    [Write the node into a file.]
646 
647   Description []
648 
649   SideEffects []
650 
651   SeeAlso     []
652 
653 ***********************************************************************/
Io_NtkWriteNodeSubckt(FILE * pFile,Abc_Obj_t * pNode,int Length)654 int Io_NtkWriteNodeSubckt( FILE * pFile, Abc_Obj_t * pNode, int Length )
655 {
656     int RetValue = 0;
657     fprintf( pFile, ".subckt" );
658     Io_NtkWriteSubcktFanins( pFile, pNode );
659     fprintf( pFile, "\n" );
660     return RetValue;
661 }
662 
663 /**Function*************************************************************
664 
665   Synopsis    [Writes the timing info.]
666 
667   Description []
668 
669   SideEffects []
670 
671   SeeAlso     []
672 
673 ***********************************************************************/
Io_WriteTimingInfo(FILE * pFile,Abc_Ntk_t * pNtk)674 void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk )
675 {
676     Abc_Obj_t * pNode;
677     Abc_Time_t * pTime, * pTimeDefIn, * pTimeDefOut;
678     int i;
679 
680     if ( pNtk->pManTime == NULL )
681         return;
682 
683     fprintf( pFile, "\n" );
684     if ( pNtk->AndGateDelay != 0.0 )
685         fprintf( pFile, ".and_gate_delay %g\n", pNtk->AndGateDelay );
686     pTimeDefIn = Abc_NtkReadDefaultArrival( pNtk );
687     //if ( pTimeDefIn->Rise != 0.0 || pTimeDefIn->Fall != 0.0 )
688         fprintf( pFile, ".default_input_arrival %g %g\n", pTimeDefIn->Rise, pTimeDefIn->Fall );
689     pTimeDefOut = Abc_NtkReadDefaultRequired( pNtk );
690     //if ( pTimeDefOut->Rise != ABC_INFINITY || pTimeDefOut->Fall != ABC_INFINITY )
691         fprintf( pFile, ".default_output_required %g %g\n", pTimeDefOut->Rise, pTimeDefOut->Fall );
692 
693     fprintf( pFile, "\n" );
694     Abc_NtkForEachPi( pNtk, pNode, i )
695     {
696         pTime = Abc_NodeReadArrival(pNode);
697         if ( pTime->Rise == pTimeDefIn->Rise && pTime->Fall == pTimeDefIn->Fall )
698             continue;
699         fprintf( pFile, ".input_arrival %s %g %g\n", Abc_ObjName(Abc_ObjFanout0(pNode)), pTime->Rise, pTime->Fall );
700     }
701     Abc_NtkForEachPo( pNtk, pNode, i )
702     {
703         pTime = Abc_NodeReadRequired(pNode);
704         if ( pTime->Rise == pTimeDefOut->Rise && pTime->Fall == pTimeDefOut->Fall )
705             continue;
706         fprintf( pFile, ".output_required %s %g %g\n", Abc_ObjName(Abc_ObjFanin0(pNode)), pTime->Rise, pTime->Fall );
707     }
708 
709     fprintf( pFile, "\n" );
710     pTimeDefIn = Abc_NtkReadDefaultInputDrive( pNtk );
711     if ( pTimeDefIn->Rise != 0.0 || pTimeDefIn->Fall != 0.0 )
712         fprintf( pFile, ".default_input_drive %g %g\n", pTimeDefIn->Rise, pTimeDefIn->Fall );
713     if ( Abc_NodeReadInputDrive( pNtk, 0 ) )
714         Abc_NtkForEachPi( pNtk, pNode, i )
715         {
716             pTime = Abc_NodeReadInputDrive( pNtk, i );
717             if ( pTime->Rise == pTimeDefIn->Rise && pTime->Fall == pTimeDefIn->Fall )
718                 continue;
719             fprintf( pFile, ".input_drive %s %g %g\n", Abc_ObjName(Abc_ObjFanout0(pNode)), pTime->Rise, pTime->Fall );
720         }
721 
722     pTimeDefOut = Abc_NtkReadDefaultOutputLoad( pNtk );
723     if ( pTimeDefOut->Rise != 0.0 || pTimeDefOut->Fall != 0.0 )
724         fprintf( pFile, ".default_output_load %g %g\n", pTimeDefOut->Rise, pTimeDefOut->Fall );
725     if ( Abc_NodeReadOutputLoad( pNtk, 0 ) )
726         Abc_NtkForEachPo( pNtk, pNode, i )
727         {
728             pTime = Abc_NodeReadOutputLoad( pNtk, i );
729             if ( pTime->Rise == pTimeDefOut->Rise && pTime->Fall == pTimeDefOut->Fall )
730                 continue;
731             fprintf( pFile, ".output_load %s %g %g\n", Abc_ObjName(Abc_ObjFanin0(pNode)), pTime->Rise, pTime->Fall );
732         }
733 
734     fprintf( pFile, "\n" );
735 }
736 
737 
738 /**Function*************************************************************
739 
740   Synopsis    []
741 
742   Description []
743 
744   SideEffects []
745 
746   SeeAlso     []
747 
748 ***********************************************************************/
Abc_NtkConvertBb2Wb(char * pFileNameIn,char * pFileNameOut,int fSeq,int fVerbose)749 void Abc_NtkConvertBb2Wb( char * pFileNameIn, char * pFileNameOut, int fSeq, int fVerbose )
750 {
751     FILE * pFile;
752     Abc_Ntk_t * pNetlist;
753     // check the files
754     pFile = fopen( pFileNameIn, "rb" );
755     if ( pFile == NULL )
756     {
757         printf( "Input file \"%s\" cannot be opened.\n", pFileNameIn );
758         return;
759     }
760     fclose( pFile );
761     // check the files
762     pFile = fopen( pFileNameOut, "wb" );
763     if ( pFile == NULL )
764     {
765         printf( "Output file \"%s\" cannot be opened.\n", pFileNameOut );
766         return;
767     }
768     fclose( pFile );
769     // derive AIG for signal correspondence
770     pNetlist = Io_ReadNetlist( pFileNameIn, Io_ReadFileType(pFileNameIn), 1 );
771     if ( pNetlist == NULL )
772     {
773         printf( "Reading input file \"%s\" has failed.\n", pFileNameIn );
774         return;
775     }
776     Io_WriteBlif( pNetlist, pFileNameOut, 1, 1, fSeq );
777     Abc_NtkDelete( pNetlist );
778 }
779 
780 
781 
782 
783 
784 
785 /**Function*************************************************************
786 
787   Synopsis    [Transforms truth table into an SOP.]
788 
789   Description []
790 
791   SideEffects []
792 
793   SeeAlso     []
794 
795 ***********************************************************************/
Io_NtkDeriveSop(Mem_Flex_t * pMem,word uTruth,int nVars,Vec_Int_t * vCover)796 char * Io_NtkDeriveSop( Mem_Flex_t * pMem, word uTruth, int nVars, Vec_Int_t * vCover )
797 {
798     char * pSop;
799     int RetValue = Kit_TruthIsop( (unsigned *)&uTruth, nVars, vCover, 1 );
800     assert( RetValue == 0 || RetValue == 1 );
801     // check the case of constant cover
802     if ( Vec_IntSize(vCover) == 0 || (Vec_IntSize(vCover) == 1 && Vec_IntEntry(vCover,0) == 0) )
803     {
804         char * pStr0 = " 0\n", * pStr1 = " 1\n";
805         assert( RetValue == 0 );
806         return Vec_IntSize(vCover) == 0 ? pStr0 : pStr1;
807     }
808     // derive the AIG for that tree
809     pSop = Abc_SopCreateFromIsop( pMem, nVars, vCover );
810     if ( RetValue )
811         Abc_SopComplement( pSop );
812     return pSop;
813 }
814 
815 /**Function*************************************************************
816 
817   Synopsis    [Write the node into a file.]
818 
819   Description []
820 
821   SideEffects []
822 
823   SeeAlso     []
824 
825 ***********************************************************************/
Io_NtkWriteNodeInt(FILE * pFile,Abc_Obj_t * pNode,Vec_Int_t * vCover)826 void Io_NtkWriteNodeInt( FILE * pFile, Abc_Obj_t * pNode, Vec_Int_t * vCover )
827 {
828     Abc_Obj_t * pNet;
829     int i, nVars = Abc_ObjFaninNum(pNode);
830     if ( nVars > 7 )
831     {
832         printf( "Node \"%s\" has more than 7 inputs. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
833         return;
834     }
835 
836     fprintf( pFile, "\n" );
837     if ( nVars <= 4 )
838     {
839         // write the .names line
840         fprintf( pFile, ".names" );
841         Abc_ObjForEachFanin( pNode, pNet, i )
842             fprintf( pFile, " %s", Abc_ObjName(pNet) );
843         // get the output name
844         fprintf( pFile, " %s\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
845         // write the cubes
846         fprintf( pFile, "%s", (char*)Abc_ObjData(pNode) );
847     }
848     else
849     {
850         extern int  If_Dec6PickBestMux( word t, word Cofs[2] );
851         extern int  If_Dec7PickBestMux( word t[2], word c0r[2], word c1r[2] );
852         extern word If_Dec6MinimumBase( word uTruth, int * pSupp, int nVarsAll, int * pnVars );
853         extern void If_Dec7MinimumBase( word uTruth[2], int * pSupp, int nVarsAll, int * pnVars );
854         extern word If_Dec6Perform( word t, int fDerive );
855         extern word If_Dec7Perform( word t[2], int fDerive );
856 
857         char * pSop;
858         word z, uTruth6 = 0, uTruth7[2], Cofs6[2], Cofs7[2][2];
859         int c, iVar, nVarsMin[2], pVars[2][10];
860 
861         // collect variables
862         Abc_ObjForEachFanin( pNode, pNet, i )
863             pVars[0][i] = pVars[1][i] = i;
864 
865         // derive truth table
866         if ( nVars == 7 )
867         {
868             Abc_SopToTruth7( (char*)Abc_ObjData(pNode), nVars, uTruth7 );
869             iVar = If_Dec7PickBestMux( uTruth7, Cofs7[0], Cofs7[1] );
870         }
871         else
872         {
873             uTruth6 = Abc_SopToTruth( (char*)Abc_ObjData(pNode), nVars );
874             iVar = If_Dec6PickBestMux( uTruth6, Cofs6 );
875         }
876 
877         // perform MUX decomposition
878         if ( iVar >= 0 )
879         {
880             if ( nVars == 7 )
881             {
882                 If_Dec7MinimumBase( Cofs7[0], pVars[0], nVars, &nVarsMin[0] );
883                 If_Dec7MinimumBase( Cofs7[1], pVars[1], nVars, &nVarsMin[1] );
884             }
885             else
886             {
887                 Cofs6[0] = If_Dec6MinimumBase( Cofs6[0], pVars[0], nVars, &nVarsMin[0] );
888                 Cofs6[1] = If_Dec6MinimumBase( Cofs6[1], pVars[1], nVars, &nVarsMin[1] );
889             }
890             assert( nVarsMin[0] < 5 );
891             assert( nVarsMin[1] < 5 );
892             // write MUX
893             fprintf( pFile, ".names" );
894             fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin(pNode,iVar)) );
895             fprintf( pFile, " %s_cascade0", Abc_ObjName(Abc_ObjFanout0(pNode)) );
896             fprintf( pFile, " %s_cascade1", Abc_ObjName(Abc_ObjFanout0(pNode)) );
897             fprintf( pFile, " %s\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
898             fprintf( pFile, "1-1 1\n01- 1\n" );
899             // write cofactors
900             for ( c = 0; c < 2; c++ )
901             {
902                 pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc,
903                     (word)(nVars == 7 ? Cofs7[c][0] : Cofs6[c]), nVarsMin[c], vCover );
904                 fprintf( pFile, ".names" );
905                 for ( i = 0; i < nVarsMin[c]; i++ )
906                     fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin(pNode,pVars[c][i])) );
907                 fprintf( pFile, " %s_cascade%d\n", Abc_ObjName(Abc_ObjFanout0(pNode)), c );
908                 fprintf( pFile, "%s", pSop );
909             }
910             return;
911         }
912         assert( nVars == 6 || nVars == 7 );
913 
914         // try cascade decomposition
915         if ( nVars == 7 )
916         {
917             z = If_Dec7Perform( uTruth7, 1 );
918             //If_Dec7Verify( uTruth7, z );
919         }
920         else
921         {
922             z = If_Dec6Perform( uTruth6, 1 );
923             //If_Dec6Verify( uTruth6, z );
924         }
925         if ( z == 0 )
926         {
927             printf( "Node \"%s\" is not decomposable. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
928             return;
929         }
930 
931         // derive nodes
932         for ( c = 1; c >= 0; c-- )
933         {
934             // collect fanins
935             uTruth7[c]  = ((c ? z >> 32 : z) & 0xffff);
936             uTruth7[c] |= (uTruth7[c] << 16);
937             uTruth7[c] |= (uTruth7[c] << 32);
938             for ( i = 0; i < 4; i++ )
939                 pVars[c][i] = (z >> (c*32+16+4*i)) & 7;
940 
941             // minimize truth table
942             Cofs6[c] = If_Dec6MinimumBase( uTruth7[c], pVars[c], 4, &nVarsMin[c] );
943 
944             // write the nodes
945             fprintf( pFile, ".names" );
946             for ( i = 0; i < nVarsMin[c]; i++ )
947                 if ( pVars[c][i] == 7 )
948                     fprintf( pFile, " %s_cascade", Abc_ObjName(Abc_ObjFanout0(pNode)) );
949                 else
950                     fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin(pNode,pVars[c][i])) );
951             fprintf( pFile, " %s%s\n", Abc_ObjName(Abc_ObjFanout0(pNode)), c? "" : "_cascade" );
952 
953             // write SOP
954             pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc,
955                 (word)Cofs6[c], nVarsMin[c], vCover );
956             fprintf( pFile, "%s", pSop );
957         }
958     }
959 }
960 
961 /**Function*************************************************************
962 
963   Synopsis    [Write the node into a file.]
964 
965   Description []
966 
967   SideEffects []
968 
969   SeeAlso     []
970 
971 ***********************************************************************/
Io_NtkWriteNodeIntStruct(FILE * pFile,Abc_Obj_t * pNode,Vec_Int_t * vCover,char * pStr)972 void Io_NtkWriteNodeIntStruct( FILE * pFile, Abc_Obj_t * pNode, Vec_Int_t * vCover, char * pStr )
973 {
974     Abc_Obj_t * pNet;
975     int nLeaves = Abc_ObjFaninNum(pNode);
976     int i, nLutLeaf, nLutLeaf2, nLutRoot, Length;
977 
978     // quit if parameters are wrong
979     Length = strlen(pStr);
980     if ( Length != 2 && Length != 3 )
981     {
982         printf( "Wrong LUT struct (%s)\n", pStr );
983         return;
984     }
985     for ( i = 0; i < Length; i++ )
986         if ( pStr[i] - '0' < 3 || pStr[i] - '0' > 6 )
987         {
988             printf( "The LUT size (%d) should belong to {3,4,5,6}.\n", pStr[i] - '0' );
989             return;
990         }
991 
992     nLutLeaf  =                   pStr[0] - '0';
993     nLutLeaf2 = ( Length == 3 ) ? pStr[1] - '0' : 0;
994     nLutRoot  =                   pStr[Length-1] - '0';
995     if ( nLeaves > nLutLeaf - 1 + (nLutLeaf2 ? nLutLeaf2 - 1 : 0) + nLutRoot )
996     {
997         printf( "The node size (%d) is too large for the LUT structure %s.\n", nLeaves, pStr );
998         return;
999     }
1000 
1001     // consider easy case
1002     fprintf( pFile, "\n" );
1003     if ( nLeaves <= Abc_MaxInt( nLutLeaf2, Abc_MaxInt(nLutLeaf, nLutRoot) ) )
1004     {
1005         // write the .names line
1006         fprintf( pFile, ".names" );
1007         Abc_ObjForEachFanin( pNode, pNet, i )
1008             fprintf( pFile, " %s", Abc_ObjName(pNet) );
1009         // get the output name
1010         fprintf( pFile, " %s\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
1011         // write the cubes
1012         fprintf( pFile, "%s", (char*)Abc_ObjData(pNode) );
1013         return;
1014     }
1015     else
1016     {
1017         extern int If_CluMinimumBase( word * t, int * pSupp, int nVarsAll, int * pnVars );
1018 
1019         static word TruthStore[16][1<<10] = {{0}}, * pTruths[16];
1020         word pCube[1<<10], pRes[1<<10], Func0, Func1, Func2;
1021         char pLut0[32], pLut1[32], pLut2[32] = {0}, * pSop;
1022 //        int nVarsMin[3], pVars[3][20];
1023 
1024         if ( TruthStore[0][0] == 0 )
1025         {
1026             static word Truth6[6] = {
1027                 ABC_CONST(0xAAAAAAAAAAAAAAAA),
1028                 ABC_CONST(0xCCCCCCCCCCCCCCCC),
1029                 ABC_CONST(0xF0F0F0F0F0F0F0F0),
1030                 ABC_CONST(0xFF00FF00FF00FF00),
1031                 ABC_CONST(0xFFFF0000FFFF0000),
1032                 ABC_CONST(0xFFFFFFFF00000000)
1033             };
1034             int nVarsMax = 16;
1035             int nWordsMax = (1 << 10);
1036             int i, k;
1037             assert( nVarsMax <= 16 );
1038             for ( i = 0; i < nVarsMax; i++ )
1039                 pTruths[i] = TruthStore[i];
1040             for ( i = 0; i < 6; i++ )
1041                 for ( k = 0; k < nWordsMax; k++ )
1042                     pTruths[i][k] = Truth6[i];
1043             for ( i = 6; i < nVarsMax; i++ )
1044                 for ( k = 0; k < nWordsMax; k++ )
1045                     pTruths[i][k] = ((k >> (i-6)) & 1) ? ~(word)0 : 0;
1046         }
1047 
1048         // collect variables
1049 //        Abc_ObjForEachFanin( pNode, pNet, i )
1050 //            pVars[0][i] = pVars[1][i] = pVars[2][i] = i;
1051 
1052         // derive truth table
1053         Abc_SopToTruthBig( (char*)Abc_ObjData(pNode), nLeaves, pTruths, pCube, pRes );
1054         if ( Kit_TruthIsConst0((unsigned *)pRes, nLeaves) || Kit_TruthIsConst1((unsigned *)pRes, nLeaves) )
1055         {
1056             fprintf( pFile, ".names %s\n %d\n", Abc_ObjName(Abc_ObjFanout0(pNode)), Kit_TruthIsConst1((unsigned *)pRes, nLeaves) );
1057             return;
1058         }
1059 
1060 //        Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves );  printf( "    " );
1061 //        Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves );  printf( "\n" );
1062 
1063         // perform decomposition
1064         if ( Length == 2 )
1065         {
1066             if ( !If_CluCheckExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
1067             {
1068                 Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves );  printf( "    " );
1069                 Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves );  printf( "\n" );
1070                 printf( "Node \"%s\" is not decomposable. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
1071                 return;
1072             }
1073         }
1074         else
1075         {
1076             if ( !If_CluCheckExt3( NULL, pRes, nLeaves, nLutLeaf, nLutLeaf2, nLutRoot, pLut0, pLut1, pLut2, &Func0, &Func1, &Func2 ) )
1077             {
1078                 Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves );  printf( "    " );
1079                 Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves );  printf( "\n" );
1080                 printf( "Node \"%s\" is not decomposable. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
1081                 return;
1082             }
1083         }
1084 
1085         // write leaf node
1086         fprintf( pFile, ".names" );
1087         for ( i = 0; i < pLut1[0]; i++ )
1088             fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin(pNode,pLut1[2+i])) );
1089         fprintf( pFile, " %s_lut1\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
1090         // write SOP
1091         pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func1, pLut1[0], vCover );
1092         fprintf( pFile, "%s", pSop );
1093 
1094         if ( Length == 3 && pLut2[0] > 0 )
1095         {
1096             // write leaf node
1097             fprintf( pFile, ".names" );
1098             for ( i = 0; i < pLut2[0]; i++ )
1099                 if ( pLut2[2+i] == nLeaves )
1100                     fprintf( pFile, " %s_lut1", Abc_ObjName(Abc_ObjFanout0(pNode)) );
1101                 else
1102                     fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin(pNode,pLut2[2+i])) );
1103             fprintf( pFile, " %s_lut2\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
1104             // write SOP
1105             pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func2, pLut2[0], vCover );
1106             fprintf( pFile, "%s", pSop );
1107         }
1108 
1109         // write root node
1110         fprintf( pFile, ".names" );
1111         for ( i = 0; i < pLut0[0]; i++ )
1112             if ( pLut0[2+i] == nLeaves )
1113                 fprintf( pFile, " %s_lut1", Abc_ObjName(Abc_ObjFanout0(pNode)) );
1114             else if ( pLut0[2+i] == nLeaves+1 )
1115                 fprintf( pFile, " %s_lut2", Abc_ObjName(Abc_ObjFanout0(pNode)) );
1116             else
1117                 fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin(pNode,pLut0[2+i])) );
1118         fprintf( pFile, " %s\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
1119         // write SOP
1120         pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func0, pLut0[0], vCover );
1121         fprintf( pFile, "%s", pSop );
1122     }
1123 }
1124 
1125 /**Function*************************************************************
1126 
1127   Synopsis    [Write the node into a file.]
1128 
1129   Description []
1130 
1131   SideEffects []
1132 
1133   SeeAlso     []
1134 
1135 ***********************************************************************/
Io_NtkWriteModelIntStruct(FILE * pFile,Abc_Obj_t * pNode,Vec_Int_t * vCover,char * pStr)1136 void Io_NtkWriteModelIntStruct( FILE * pFile, Abc_Obj_t * pNode, Vec_Int_t * vCover, char * pStr )
1137 {
1138     Abc_Obj_t * pNet;
1139     int nLeaves = Abc_ObjFaninNum(pNode);
1140     int i, nLutLeaf, nLutLeaf2, nLutRoot, Length;
1141 
1142     // write the header
1143     fprintf( pFile, "\n" );
1144     fprintf( pFile, ".model m%d\n", Abc_ObjId(pNode) );
1145     fprintf( pFile, ".inputs" );
1146     for ( i = 0; i < Abc_ObjFaninNum(pNode); i++ )
1147         fprintf( pFile, " %c", 'a' + i );
1148     fprintf( pFile, "\n" );
1149     fprintf( pFile, ".outputs o\n" );
1150 
1151     // quit if parameters are wrong
1152     Length = strlen(pStr);
1153     if ( Length != 2 && Length != 3 )
1154     {
1155         printf( "Wrong LUT struct (%s)\n", pStr );
1156         return;
1157     }
1158     for ( i = 0; i < Length; i++ )
1159         if ( pStr[i] - '0' < 3 || pStr[i] - '0' > 6 )
1160         {
1161             printf( "The LUT size (%d) should belong to {3,4,5,6}.\n", pStr[i] - '0' );
1162             return;
1163         }
1164 
1165     nLutLeaf  =                   pStr[0] - '0';
1166     nLutLeaf2 = ( Length == 3 ) ? pStr[1] - '0' : 0;
1167     nLutRoot  =                   pStr[Length-1] - '0';
1168     if ( nLeaves > nLutLeaf - 1 + (nLutLeaf2 ? nLutLeaf2 - 1 : 0) + nLutRoot )
1169     {
1170         printf( "The node size (%d) is too large for the LUT structure %s.\n", nLeaves, pStr );
1171         return;
1172     }
1173 
1174     // consider easy case
1175     if ( nLeaves <= Abc_MaxInt( nLutLeaf2, Abc_MaxInt(nLutLeaf, nLutRoot) ) )
1176     {
1177         // write the .names line
1178         fprintf( pFile, ".names" );
1179         Abc_ObjForEachFanin( pNode, pNet, i )
1180             fprintf( pFile, " %c", 'a' + i );
1181         // get the output name
1182         fprintf( pFile, " %s\n", "o" );
1183         // write the cubes
1184         fprintf( pFile, "%s", (char*)Abc_ObjData(pNode) );
1185         fprintf( pFile, ".end\n" );
1186         return;
1187     }
1188     else
1189     {
1190         extern int If_CluMinimumBase( word * t, int * pSupp, int nVarsAll, int * pnVars );
1191 
1192         static word TruthStore[16][1<<10] = {{0}}, * pTruths[16];
1193         word pCube[1<<10], pRes[1<<10], Func0, Func1, Func2;
1194         char pLut0[32], pLut1[32], pLut2[32] = {0}, * pSop;
1195 //        int nVarsMin[3], pVars[3][20];
1196 
1197         if ( TruthStore[0][0] == 0 )
1198         {
1199             static word Truth6[6] = {
1200                 ABC_CONST(0xAAAAAAAAAAAAAAAA),
1201                 ABC_CONST(0xCCCCCCCCCCCCCCCC),
1202                 ABC_CONST(0xF0F0F0F0F0F0F0F0),
1203                 ABC_CONST(0xFF00FF00FF00FF00),
1204                 ABC_CONST(0xFFFF0000FFFF0000),
1205                 ABC_CONST(0xFFFFFFFF00000000)
1206             };
1207             int nVarsMax = 16;
1208             int nWordsMax = (1 << 10);
1209             int i, k;
1210             assert( nVarsMax <= 16 );
1211             for ( i = 0; i < nVarsMax; i++ )
1212                 pTruths[i] = TruthStore[i];
1213             for ( i = 0; i < 6; i++ )
1214                 for ( k = 0; k < nWordsMax; k++ )
1215                     pTruths[i][k] = Truth6[i];
1216             for ( i = 6; i < nVarsMax; i++ )
1217                 for ( k = 0; k < nWordsMax; k++ )
1218                     pTruths[i][k] = ((k >> (i-6)) & 1) ? ~(word)0 : 0;
1219         }
1220 
1221         // collect variables
1222 //        Abc_ObjForEachFanin( pNode, pNet, i )
1223 //            pVars[0][i] = pVars[1][i] = pVars[2][i] = i;
1224 
1225         // derive truth table
1226         Abc_SopToTruthBig( (char*)Abc_ObjData(pNode), nLeaves, pTruths, pCube, pRes );
1227         if ( Kit_TruthIsConst0((unsigned *)pRes, nLeaves) || Kit_TruthIsConst1((unsigned *)pRes, nLeaves) )
1228         {
1229             fprintf( pFile, ".names %s\n %d\n", "o", Kit_TruthIsConst1((unsigned *)pRes, nLeaves) );
1230             fprintf( pFile, ".end\n" );
1231             return;
1232         }
1233 
1234 //        Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves );  printf( "    " );
1235 //        Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves );  printf( "\n" );
1236 
1237         // perform decomposition
1238         if ( Length == 2 )
1239         {
1240             if ( !If_CluCheckExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
1241             {
1242                 Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves );  printf( "    " );
1243                 Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves );  printf( "\n" );
1244                 printf( "Node \"%s\" is not decomposable. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
1245                 return;
1246             }
1247         }
1248         else
1249         {
1250             if ( !If_CluCheckExt3( NULL, pRes, nLeaves, nLutLeaf, nLutLeaf2, nLutRoot, pLut0, pLut1, pLut2, &Func0, &Func1, &Func2 ) )
1251             {
1252                 Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves );  printf( "    " );
1253                 Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves );  printf( "\n" );
1254                 printf( "Node \"%s\" is not decomposable. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
1255                 return;
1256             }
1257         }
1258 
1259         // write leaf node
1260         fprintf( pFile, ".names" );
1261         for ( i = 0; i < pLut1[0]; i++ )
1262             fprintf( pFile, " %c", 'a' + pLut1[2+i] );
1263         fprintf( pFile, " lut1\n" );
1264         // write SOP
1265         pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func1, pLut1[0], vCover );
1266         fprintf( pFile, "%s", pSop );
1267 
1268         if ( Length == 3 && pLut2[0] > 0 )
1269         {
1270             // write leaf node
1271             fprintf( pFile, ".names" );
1272             for ( i = 0; i < pLut2[0]; i++ )
1273                 if ( pLut2[2+i] == nLeaves )
1274                     fprintf( pFile, " lut1" );
1275                 else
1276                     fprintf( pFile, " %c", 'a' + pLut2[2+i] );
1277             fprintf( pFile, " lut2\n" );
1278             // write SOP
1279             pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func2, pLut2[0], vCover );
1280             fprintf( pFile, "%s", pSop );
1281         }
1282 
1283         // write root node
1284         fprintf( pFile, ".names" );
1285         for ( i = 0; i < pLut0[0]; i++ )
1286             if ( pLut0[2+i] == nLeaves )
1287                 fprintf( pFile, " lut1" );
1288             else if ( pLut0[2+i] == nLeaves+1 )
1289                 fprintf( pFile, " lut2" );
1290             else
1291                 fprintf( pFile, " %c", 'a' + pLut0[2+i] );
1292         fprintf( pFile, " %s\n", "o" );
1293         // write SOP
1294         pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func0, pLut0[0], vCover );
1295         fprintf( pFile, "%s", pSop );
1296         fprintf( pFile, ".end\n" );
1297     }
1298 }
1299 
1300 
1301 /**Function*************************************************************
1302 
1303   Synopsis    [Write the network into a BLIF file with the given name.]
1304 
1305   Description []
1306 
1307   SideEffects []
1308 
1309   SeeAlso     []
1310 
1311 ***********************************************************************/
Io_WriteBlifInt(Abc_Ntk_t * pNtk,char * FileName,char * pLutStruct,int fUseHie)1312 void Io_WriteBlifInt( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct, int fUseHie )
1313 {
1314     FILE * pFile;
1315     Vec_Int_t * vCover;
1316     Abc_Obj_t * pNode, * pLatch;
1317     int i;
1318     assert( Abc_NtkIsNetlist(pNtk) );
1319     // start writing the file
1320     pFile = fopen( FileName, "w" );
1321     if ( pFile == NULL )
1322     {
1323         fprintf( stdout, "Io_WriteBlifInt(): Cannot open the output file.\n" );
1324         return;
1325     }
1326     fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
1327     // write the model name
1328     fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) );
1329     // write the PIs
1330     fprintf( pFile, ".inputs" );
1331     Io_NtkWritePis( pFile, pNtk, 1 );
1332     fprintf( pFile, "\n" );
1333     // write the POs
1334     fprintf( pFile, ".outputs" );
1335     Io_NtkWritePos( pFile, pNtk, 1 );
1336     fprintf( pFile, "\n" );
1337     // write the latches
1338     if ( Abc_NtkLatchNum(pNtk) )
1339         fprintf( pFile, "\n" );
1340     Abc_NtkForEachLatch( pNtk, pLatch, i )
1341         Io_NtkWriteLatch( pFile, pLatch );
1342     if ( Abc_NtkLatchNum(pNtk) )
1343         fprintf( pFile, "\n" );
1344     // write the hierarchy
1345     vCover = Vec_IntAlloc( (1<<16) );
1346     if ( fUseHie )
1347     {
1348         // write each internal node
1349         fprintf( pFile, "\n" );
1350         Abc_NtkForEachNode( pNtk, pNode, i )
1351             Io_NtkWriteNodeSubckt( pFile, pNode, 0 );
1352         fprintf( pFile, ".end\n\n" );
1353         // write models
1354         Abc_NtkForEachNode( pNtk, pNode, i )
1355             Io_NtkWriteModelIntStruct( pFile, pNode, vCover, pLutStruct );
1356         fprintf( pFile, "\n" );
1357     }
1358     else
1359     {
1360         // write each internal node
1361         Abc_NtkForEachNode( pNtk, pNode, i )
1362         {
1363             if ( pLutStruct )
1364                 Io_NtkWriteNodeIntStruct( pFile, pNode, vCover, pLutStruct );
1365             else
1366                 Io_NtkWriteNodeInt( pFile, pNode, vCover );
1367         }
1368         fprintf( pFile, ".end\n\n" );
1369     }
1370     Vec_IntFree( vCover );
1371     fclose( pFile );
1372 }
1373 
1374 /**Function*************************************************************
1375 
1376   Synopsis    [Write the network into a BLIF file with the given name.]
1377 
1378   Description []
1379 
1380   SideEffects []
1381 
1382   SeeAlso     []
1383 
1384 ***********************************************************************/
Io_WriteBlifSpecial(Abc_Ntk_t * pNtk,char * FileName,char * pLutStruct,int fUseHie)1385 void Io_WriteBlifSpecial( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct, int fUseHie )
1386 {
1387     Abc_Ntk_t * pNtkTemp;
1388     assert( Abc_NtkIsLogic(pNtk) );
1389     Abc_NtkToSop( pNtk, -1, ABC_INFINITY );
1390     // derive the netlist
1391     pNtkTemp = Abc_NtkToNetlist(pNtk);
1392     if ( pNtkTemp == NULL )
1393     {
1394         fprintf( stdout, "Writing BLIF has failed.\n" );
1395         return;
1396     }
1397     if ( pLutStruct && fUseHie )
1398         Io_WriteBlifInt( pNtkTemp, FileName, pLutStruct, 1 );
1399     else
1400         Io_WriteBlifInt( pNtkTemp, FileName, pLutStruct, 0 );
1401     Abc_NtkDelete( pNtkTemp );
1402 }
1403 
1404 ////////////////////////////////////////////////////////////////////////
1405 ///                       END OF FILE                                ///
1406 ////////////////////////////////////////////////////////////////////////
1407 
1408 
1409 ABC_NAMESPACE_IMPL_END
1410 
1411