PageRenderTime 64ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/src/aig/gia/giaAiger.c

https://bitbucket.org/alanmi/abc/
C | 1479 lines | 1120 code | 66 blank | 293 comment | 372 complexity | d2adb49cdb68a957ab13a04502ec3a4b MD5 | raw file
Possible License(s): BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /**CFile****************************************************************
  2. FileName [giaAiger.c]
  3. SystemName [ABC: Logic synthesis and verification system.]
  4. PackageName [Scalable AIG package.]
  5. Synopsis [Procedures to read/write binary AIGER format developed by
  6. Armin Biere, Johannes Kepler University (http://fmv.jku.at/)]
  7. Author [Alan Mishchenko]
  8. Affiliation [UC Berkeley]
  9. Date [Ver. 1.0. Started - June 20, 2005.]
  10. Revision [$Id: giaAiger.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
  11. ***********************************************************************/
  12. #include "gia.h"
  13. #include "misc/tim/tim.h"
  14. #include "base/main/main.h"
  15. ABC_NAMESPACE_IMPL_START
  16. #define XAIG_VERBOSE 0
  17. ////////////////////////////////////////////////////////////////////////
  18. /// DECLARATIONS ///
  19. ////////////////////////////////////////////////////////////////////////
  20. ////////////////////////////////////////////////////////////////////////
  21. /// FUNCTION DEFINITIONS ///
  22. ////////////////////////////////////////////////////////////////////////
  23. /**Function*************************************************************
  24. Synopsis []
  25. Description []
  26. SideEffects []
  27. SeeAlso []
  28. ***********************************************************************/
  29. void Gia_FileFixName( char * pFileName )
  30. {
  31. char * pName;
  32. for ( pName = pFileName; *pName; pName++ )
  33. if ( *pName == '>' )
  34. *pName = '\\';
  35. }
  36. char * Gia_FileNameGeneric( char * FileName )
  37. {
  38. char * pDot, * pRes;
  39. pRes = Abc_UtilStrsav( FileName );
  40. if ( (pDot = strrchr( pRes, '.' )) )
  41. *pDot = 0;
  42. return pRes;
  43. }
  44. int Gia_FileSize( char * pFileName )
  45. {
  46. FILE * pFile;
  47. int nFileSize;
  48. pFile = fopen( pFileName, "r" );
  49. if ( pFile == NULL )
  50. {
  51. printf( "Gia_FileSize(): The file is unavailable (absent or open).\n" );
  52. return 0;
  53. }
  54. fseek( pFile, 0, SEEK_END );
  55. nFileSize = ftell( pFile );
  56. fclose( pFile );
  57. return nFileSize;
  58. }
  59. void Gia_FileWriteBufferSize( FILE * pFile, int nSize )
  60. {
  61. unsigned char Buffer[5];
  62. Gia_AigerWriteInt( Buffer, nSize );
  63. fwrite( Buffer, 1, 4, pFile );
  64. }
  65. /**Function*************************************************************
  66. Synopsis [Create the array of literals to be written.]
  67. Description []
  68. SideEffects []
  69. SeeAlso []
  70. ***********************************************************************/
  71. Vec_Int_t * Gia_AigerCollectLiterals( Gia_Man_t * p )
  72. {
  73. Vec_Int_t * vLits;
  74. Gia_Obj_t * pObj;
  75. int i;
  76. vLits = Vec_IntAlloc( Gia_ManPoNum(p) );
  77. Gia_ManForEachRi( p, pObj, i )
  78. Vec_IntPush( vLits, Gia_ObjFaninLit0p(p, pObj) );
  79. Gia_ManForEachPo( p, pObj, i )
  80. Vec_IntPush( vLits, Gia_ObjFaninLit0p(p, pObj) );
  81. return vLits;
  82. }
  83. Vec_Int_t * Gia_AigerReadLiterals( unsigned char ** ppPos, int nEntries )
  84. {
  85. Vec_Int_t * vLits;
  86. int Lit, LitPrev, Diff, i;
  87. vLits = Vec_IntAlloc( nEntries );
  88. LitPrev = Gia_AigerReadUnsigned( ppPos );
  89. Vec_IntPush( vLits, LitPrev );
  90. for ( i = 1; i < nEntries; i++ )
  91. {
  92. // Diff = Lit - LitPrev;
  93. // Diff = (Lit < LitPrev)? -Diff : Diff;
  94. // Diff = ((2 * Diff) << 1) | (int)(Lit < LitPrev);
  95. Diff = Gia_AigerReadUnsigned( ppPos );
  96. Diff = (Diff & 1)? -(Diff >> 1) : Diff >> 1;
  97. Lit = Diff + LitPrev;
  98. Vec_IntPush( vLits, Lit );
  99. LitPrev = Lit;
  100. }
  101. return vLits;
  102. }
  103. Vec_Str_t * Gia_AigerWriteLiterals( Vec_Int_t * vLits )
  104. {
  105. Vec_Str_t * vBinary;
  106. int Pos = 0, Lit, LitPrev, Diff, i;
  107. vBinary = Vec_StrAlloc( 2 * Vec_IntSize(vLits) );
  108. LitPrev = Vec_IntEntry( vLits, 0 );
  109. Pos = Gia_AigerWriteUnsignedBuffer( (unsigned char *)Vec_StrArray(vBinary), Pos, LitPrev );
  110. Vec_IntForEachEntryStart( vLits, Lit, i, 1 )
  111. {
  112. Diff = Lit - LitPrev;
  113. Diff = (Lit < LitPrev)? -Diff : Diff;
  114. Diff = (Diff << 1) | (int)(Lit < LitPrev);
  115. Pos = Gia_AigerWriteUnsignedBuffer( (unsigned char *)Vec_StrArray(vBinary), Pos, Diff );
  116. LitPrev = Lit;
  117. if ( Pos + 10 > vBinary->nCap )
  118. Vec_StrGrow( vBinary, vBinary->nCap+1 );
  119. }
  120. vBinary->nSize = Pos;
  121. /*
  122. // verify
  123. {
  124. extern Vec_Int_t * Gia_AigerReadLiterals( char ** ppPos, int nEntries );
  125. char * pPos = Vec_StrArray( vBinary );
  126. Vec_Int_t * vTemp = Gia_AigerReadLiterals( &pPos, Vec_IntSize(vLits) );
  127. for ( i = 0; i < Vec_IntSize(vLits); i++ )
  128. {
  129. int Entry1 = Vec_IntEntry(vLits,i);
  130. int Entry2 = Vec_IntEntry(vTemp,i);
  131. assert( Entry1 == Entry2 );
  132. }
  133. Vec_IntFree( vTemp );
  134. }
  135. */
  136. return vBinary;
  137. }
  138. /**Function*************************************************************
  139. Synopsis [Reads the AIG in the binary AIGER format.]
  140. Description []
  141. SideEffects []
  142. SeeAlso []
  143. ***********************************************************************/
  144. Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSimple, int fSkipStrash, int fCheck )
  145. {
  146. Gia_Man_t * pNew, * pTemp;
  147. Vec_Int_t * vLits = NULL, * vPoTypes = NULL;
  148. Vec_Int_t * vNodes, * vDrivers, * vInits = NULL;
  149. int iObj, iNode0, iNode1, fHieOnly = 0;
  150. int nTotal, nInputs, nOutputs, nLatches, nAnds, i;
  151. int nBad = 0, nConstr = 0, nJust = 0, nFair = 0;
  152. unsigned char * pDrivers, * pSymbols, * pCur;
  153. unsigned uLit0, uLit1, uLit;
  154. // read the parameters (M I L O A + B C J F)
  155. pCur = (unsigned char *)pContents; while ( *pCur != ' ' ) pCur++; pCur++;
  156. // read the number of objects
  157. nTotal = atoi( (const char *)pCur ); while ( *pCur != ' ' ) pCur++; pCur++;
  158. // read the number of inputs
  159. nInputs = atoi( (const char *)pCur ); while ( *pCur != ' ' ) pCur++; pCur++;
  160. // read the number of latches
  161. nLatches = atoi( (const char *)pCur ); while ( *pCur != ' ' ) pCur++; pCur++;
  162. // read the number of outputs
  163. nOutputs = atoi( (const char *)pCur ); while ( *pCur != ' ' ) pCur++; pCur++;
  164. // read the number of nodes
  165. nAnds = atoi( (const char *)pCur ); while ( *pCur != ' ' && *pCur != '\n' ) pCur++;
  166. if ( *pCur == ' ' )
  167. {
  168. // assert( nOutputs == 0 );
  169. // read the number of properties
  170. pCur++;
  171. nBad = atoi( (const char *)pCur ); while ( *pCur != ' ' && *pCur != '\n' ) pCur++;
  172. nOutputs += nBad;
  173. }
  174. if ( *pCur == ' ' )
  175. {
  176. // read the number of properties
  177. pCur++;
  178. nConstr = atoi( (const char *)pCur ); while ( *pCur != ' ' && *pCur != '\n' ) pCur++;
  179. nOutputs += nConstr;
  180. }
  181. if ( *pCur == ' ' )
  182. {
  183. // read the number of properties
  184. pCur++;
  185. nJust = atoi( (const char *)pCur ); while ( *pCur != ' ' && *pCur != '\n' ) pCur++;
  186. nOutputs += nJust;
  187. }
  188. if ( *pCur == ' ' )
  189. {
  190. // read the number of properties
  191. pCur++;
  192. nFair = atoi( (const char *)pCur ); while ( *pCur != ' ' && *pCur != '\n' ) pCur++;
  193. nOutputs += nFair;
  194. }
  195. if ( *pCur != '\n' )
  196. {
  197. fprintf( stdout, "The parameter line is in a wrong format.\n" );
  198. return NULL;
  199. }
  200. pCur++;
  201. // check the parameters
  202. if ( nTotal != nInputs + nLatches + nAnds )
  203. {
  204. fprintf( stdout, "The number of objects does not match.\n" );
  205. return NULL;
  206. }
  207. if ( nJust || nFair )
  208. {
  209. fprintf( stdout, "Reading AIGER files with liveness properties is currently not supported.\n" );
  210. return NULL;
  211. }
  212. if ( nConstr )
  213. {
  214. if ( nConstr == 1 )
  215. fprintf( stdout, "Warning: The last output is interpreted as a constraint.\n" );
  216. else
  217. fprintf( stdout, "Warning: The last %d outputs are interpreted as constraints.\n", nConstr );
  218. }
  219. // allocate the empty AIG
  220. pNew = Gia_ManStart( nTotal + nLatches + nOutputs + 1 );
  221. pNew->nConstrs = nConstr;
  222. pNew->fGiaSimple = fGiaSimple;
  223. // prepare the array of nodes
  224. vNodes = Vec_IntAlloc( 1 + nTotal );
  225. Vec_IntPush( vNodes, 0 );
  226. // create the PIs
  227. for ( i = 0; i < nInputs + nLatches; i++ )
  228. {
  229. iObj = Gia_ManAppendCi(pNew);
  230. Vec_IntPush( vNodes, iObj );
  231. }
  232. // remember the beginning of latch/PO literals
  233. pDrivers = pCur;
  234. if ( pContents[3] == ' ' ) // standard AIGER
  235. {
  236. // scroll to the beginning of the binary data
  237. for ( i = 0; i < nLatches + nOutputs; )
  238. if ( *pCur++ == '\n' )
  239. i++;
  240. }
  241. else // modified AIGER
  242. {
  243. vLits = Gia_AigerReadLiterals( &pCur, nLatches + nOutputs );
  244. }
  245. // create the AND gates
  246. if ( !fGiaSimple && !fSkipStrash )
  247. Gia_ManHashAlloc( pNew );
  248. for ( i = 0; i < nAnds; i++ )
  249. {
  250. uLit = ((i + 1 + nInputs + nLatches) << 1);
  251. uLit1 = uLit - Gia_AigerReadUnsigned( &pCur );
  252. uLit0 = uLit1 - Gia_AigerReadUnsigned( &pCur );
  253. // assert( uLit1 > uLit0 );
  254. iNode0 = Abc_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), uLit0 & 1 );
  255. iNode1 = Abc_LitNotCond( Vec_IntEntry(vNodes, uLit1 >> 1), uLit1 & 1 );
  256. assert( Vec_IntSize(vNodes) == i + 1 + nInputs + nLatches );
  257. if ( !fGiaSimple && fSkipStrash )
  258. {
  259. if ( iNode0 == iNode1 )
  260. Vec_IntPush( vNodes, Gia_ManAppendBuf(pNew, iNode0) );
  261. else
  262. Vec_IntPush( vNodes, Gia_ManAppendAnd(pNew, iNode0, iNode1) );
  263. }
  264. else
  265. Vec_IntPush( vNodes, Gia_ManHashAnd(pNew, iNode0, iNode1) );
  266. }
  267. if ( !fGiaSimple && !fSkipStrash )
  268. Gia_ManHashStop( pNew );
  269. // remember the place where symbols begin
  270. pSymbols = pCur;
  271. // read the latch driver literals
  272. vDrivers = Vec_IntAlloc( nLatches + nOutputs );
  273. if ( pContents[3] == ' ' ) // standard AIGER
  274. {
  275. vInits = Vec_IntAlloc( nLatches );
  276. pCur = pDrivers;
  277. for ( i = 0; i < nLatches; i++ )
  278. {
  279. uLit0 = atoi( (char *)pCur );
  280. while ( *pCur != ' ' && *pCur != '\n' )
  281. pCur++;
  282. if ( *pCur == ' ' )
  283. {
  284. pCur++;
  285. Vec_IntPush( vInits, atoi( (char *)pCur ) );
  286. while ( *pCur++ != '\n' );
  287. }
  288. else
  289. {
  290. pCur++;
  291. Vec_IntPush( vInits, 0 );
  292. }
  293. iNode0 = Abc_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
  294. Vec_IntPush( vDrivers, iNode0 );
  295. }
  296. // read the PO driver literals
  297. for ( i = 0; i < nOutputs; i++ )
  298. {
  299. uLit0 = atoi( (char *)pCur ); while ( *pCur++ != '\n' );
  300. iNode0 = Abc_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
  301. Vec_IntPush( vDrivers, iNode0 );
  302. }
  303. }
  304. else
  305. {
  306. // read the latch driver literals
  307. for ( i = 0; i < nLatches; i++ )
  308. {
  309. uLit0 = Vec_IntEntry( vLits, i );
  310. iNode0 = Abc_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
  311. Vec_IntPush( vDrivers, iNode0 );
  312. }
  313. // read the PO driver literals
  314. for ( i = 0; i < nOutputs; i++ )
  315. {
  316. uLit0 = Vec_IntEntry( vLits, i+nLatches );
  317. iNode0 = Abc_LitNotCond( Vec_IntEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
  318. Vec_IntPush( vDrivers, iNode0 );
  319. }
  320. Vec_IntFree( vLits );
  321. }
  322. // create the POs
  323. for ( i = 0; i < nOutputs; i++ )
  324. Gia_ManAppendCo( pNew, Vec_IntEntry(vDrivers, nLatches + i) );
  325. for ( i = 0; i < nLatches; i++ )
  326. Gia_ManAppendCo( pNew, Vec_IntEntry(vDrivers, i) );
  327. Vec_IntFree( vDrivers );
  328. // create the latches
  329. Gia_ManSetRegNum( pNew, nLatches );
  330. // read signal names if they are of the special type
  331. pCur = pSymbols;
  332. if ( pCur < (unsigned char *)pContents + nFileSize && *pCur != 'c' )
  333. {
  334. int fBreakUsed = 0;
  335. unsigned char * pCurOld = pCur;
  336. pNew->vUserPiIds = Vec_IntStartFull( nInputs );
  337. pNew->vUserPoIds = Vec_IntStartFull( nOutputs );
  338. pNew->vUserFfIds = Vec_IntStartFull( nLatches );
  339. while ( pCur < (unsigned char *)pContents + nFileSize && *pCur != 'c' )
  340. {
  341. int iTerm;
  342. char * pType = (char *)pCur;
  343. // check terminal type
  344. if ( *pCur != 'i' && *pCur != 'o' && *pCur != 'l' )
  345. {
  346. // fprintf( stdout, "Wrong terminal type.\n" );
  347. fBreakUsed = 1;
  348. break;
  349. }
  350. // get terminal number
  351. iTerm = atoi( (char *)++pCur ); while ( *pCur++ != ' ' );
  352. // skip spaces
  353. while ( *pCur == ' ' )
  354. pCur++;
  355. // decode the user numbers:
  356. // flops are named: @l<num>
  357. // PIs are named: @i<num>
  358. // POs are named: @o<num>
  359. if ( *pCur++ != '@' )
  360. {
  361. fBreakUsed = 1;
  362. break;
  363. }
  364. if ( *pCur == 'i' && *pType == 'i' )
  365. Vec_IntWriteEntry( pNew->vUserPiIds, iTerm, atoi((char *)pCur+1) );
  366. else if ( *pCur == 'o' && *pType == 'o' )
  367. Vec_IntWriteEntry( pNew->vUserPoIds, iTerm, atoi((char *)pCur+1) );
  368. else if ( *pCur == 'l' && *pType == 'l' )
  369. Vec_IntWriteEntry( pNew->vUserFfIds, iTerm, atoi((char *)pCur+1) );
  370. else
  371. {
  372. fprintf( stdout, "Wrong name format.\n" );
  373. fBreakUsed = 1;
  374. break;
  375. }
  376. // skip digits
  377. while ( *pCur++ != '\n' );
  378. }
  379. // in case of abnormal termination, remove the arrays
  380. if ( fBreakUsed )
  381. {
  382. unsigned char * pName;
  383. int Entry, nInvars, nConstr, iTerm;
  384. Vec_Int_t * vPoNames = Vec_IntStartFull( nOutputs );
  385. Vec_IntFreeP( &pNew->vUserPiIds );
  386. Vec_IntFreeP( &pNew->vUserPoIds );
  387. Vec_IntFreeP( &pNew->vUserFfIds );
  388. // try to figure out signal names
  389. fBreakUsed = 0;
  390. pCur = (unsigned char *)pCurOld;
  391. while ( pCur < (unsigned char *)pContents + nFileSize && *pCur != 'c' )
  392. {
  393. // get the terminal type
  394. if ( *pCur == 'i' || *pCur == 'l' )
  395. {
  396. // skip till the end of the line
  397. while ( *pCur++ != '\n' );
  398. *(pCur-1) = 0;
  399. continue;
  400. }
  401. if ( *pCur != 'o' )
  402. {
  403. // fprintf( stdout, "Wrong terminal type.\n" );
  404. fBreakUsed = 1;
  405. break;
  406. }
  407. // get the terminal number
  408. iTerm = atoi( (char *)++pCur ); while ( *pCur++ != ' ' );
  409. // get the node
  410. if ( iTerm < 0 || iTerm >= nOutputs )
  411. {
  412. fprintf( stdout, "The output number (%d) is out of range.\n", iTerm );
  413. fBreakUsed = 1;
  414. break;
  415. }
  416. if ( Vec_IntEntry(vPoNames, iTerm) != ~0 )
  417. {
  418. fprintf( stdout, "The output number (%d) is listed twice.\n", iTerm );
  419. fBreakUsed = 1;
  420. break;
  421. }
  422. // get the name
  423. pName = pCur; while ( *pCur++ != '\n' );
  424. *(pCur-1) = 0;
  425. // assign the name
  426. Vec_IntWriteEntry( vPoNames, iTerm, pName - (unsigned char *)pContents );
  427. }
  428. // check that all names are assigned
  429. if ( !fBreakUsed )
  430. {
  431. nInvars = nConstr = 0;
  432. vPoTypes = Vec_IntStart( Gia_ManPoNum(pNew) );
  433. Vec_IntForEachEntry( vPoNames, Entry, i )
  434. {
  435. if ( Entry == ~0 )
  436. continue;
  437. if ( strncmp( pContents+Entry, "constraint:", 11 ) == 0 )
  438. {
  439. Vec_IntWriteEntry( vPoTypes, i, 1 );
  440. nConstr++;
  441. }
  442. if ( strncmp( pContents+Entry, "invariant:", 10 ) == 0 )
  443. {
  444. Vec_IntWriteEntry( vPoTypes, i, 2 );
  445. nInvars++;
  446. }
  447. }
  448. if ( nConstr )
  449. fprintf( stdout, "Recognized and added %d constraints.\n", nConstr );
  450. if ( nInvars )
  451. fprintf( stdout, "Recognized and skipped %d invariants.\n", nInvars );
  452. if ( nConstr == 0 && nInvars == 0 )
  453. Vec_IntFreeP( &vPoTypes );
  454. }
  455. Vec_IntFree( vPoNames );
  456. }
  457. }
  458. // check if there are other types of information to read
  459. if ( pCur + 1 < (unsigned char *)pContents + nFileSize && *pCur == 'c' )
  460. {
  461. int fVerbose = XAIG_VERBOSE;
  462. Vec_Str_t * vStr;
  463. unsigned char * pCurTemp;
  464. pCur++;
  465. // skip new line if present
  466. // if ( *pCur == '\n' )
  467. // pCur++;
  468. while ( pCur < (unsigned char *)pContents + nFileSize )
  469. {
  470. // read extra AIG
  471. if ( *pCur == 'a' )
  472. {
  473. pCur++;
  474. vStr = Vec_StrStart( Gia_AigerReadInt(pCur) ); pCur += 4;
  475. memcpy( Vec_StrArray(vStr), pCur, Vec_StrSize(vStr) );
  476. pCur += Vec_StrSize(vStr);
  477. pNew->pAigExtra = Gia_AigerReadFromMemory( Vec_StrArray(vStr), Vec_StrSize(vStr), 0, 0, 0 );
  478. Vec_StrFree( vStr );
  479. if ( fVerbose ) printf( "Finished reading extension \"a\".\n" );
  480. }
  481. // read number of constraints
  482. else if ( *pCur == 'c' )
  483. {
  484. pCur++;
  485. assert( Gia_AigerReadInt(pCur) == 4 ); pCur += 4;
  486. pNew->nConstrs = Gia_AigerReadInt( pCur ); pCur += 4;
  487. if ( fVerbose ) printf( "Finished reading extension \"c\".\n" );
  488. }
  489. // read delay information
  490. else if ( *pCur == 'd' )
  491. {
  492. pCur++;
  493. assert( Gia_AigerReadInt(pCur) == 4 ); pCur += 4;
  494. pNew->nAnd2Delay = Gia_AigerReadInt(pCur); pCur += 4;
  495. if ( fVerbose ) printf( "Finished reading extension \"d\".\n" );
  496. }
  497. else if ( *pCur == 'i' )
  498. {
  499. pCur++;
  500. nInputs = Gia_AigerReadInt(pCur)/4; pCur += 4;
  501. pNew->vInArrs = Vec_FltStart( nInputs );
  502. memcpy( Vec_FltArray(pNew->vInArrs), pCur, 4*nInputs ); pCur += 4*nInputs;
  503. if ( fVerbose ) printf( "Finished reading extension \"i\".\n" );
  504. }
  505. else if ( *pCur == 'o' )
  506. {
  507. pCur++;
  508. nOutputs = Gia_AigerReadInt(pCur)/4; pCur += 4;
  509. pNew->vOutReqs = Vec_FltStart( nOutputs );
  510. memcpy( Vec_FltArray(pNew->vOutReqs), pCur, 4*nOutputs ); pCur += 4*nOutputs;
  511. if ( fVerbose ) printf( "Finished reading extension \"o\".\n" );
  512. }
  513. // read equivalence classes
  514. else if ( *pCur == 'e' )
  515. {
  516. extern Gia_Rpr_t * Gia_AigerReadEquivClasses( unsigned char ** ppPos, int nSize );
  517. pCur++;
  518. pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
  519. pNew->pReprs = Gia_AigerReadEquivClasses( &pCur, Gia_ManObjNum(pNew) );
  520. pNew->pNexts = Gia_ManDeriveNexts( pNew );
  521. assert( pCur == pCurTemp );
  522. if ( fVerbose ) printf( "Finished reading extension \"e\".\n" );
  523. }
  524. // read flop classes
  525. else if ( *pCur == 'f' )
  526. {
  527. pCur++;
  528. assert( Gia_AigerReadInt(pCur) == 4*Gia_ManRegNum(pNew) ); pCur += 4;
  529. pNew->vFlopClasses = Vec_IntStart( Gia_ManRegNum(pNew) );
  530. memcpy( Vec_IntArray(pNew->vFlopClasses), pCur, 4*Gia_ManRegNum(pNew) ); pCur += 4*Gia_ManRegNum(pNew);
  531. if ( fVerbose ) printf( "Finished reading extension \"f\".\n" );
  532. }
  533. // read gate classes
  534. else if ( *pCur == 'g' )
  535. {
  536. pCur++;
  537. assert( Gia_AigerReadInt(pCur) == 4*Gia_ManObjNum(pNew) ); pCur += 4;
  538. pNew->vGateClasses = Vec_IntStart( Gia_ManObjNum(pNew) );
  539. memcpy( Vec_IntArray(pNew->vGateClasses), pCur, 4*Gia_ManObjNum(pNew) ); pCur += 4*Gia_ManObjNum(pNew);
  540. if ( fVerbose ) printf( "Finished reading extension \"g\".\n" );
  541. }
  542. // read hierarchy information
  543. else if ( *pCur == 'h' )
  544. {
  545. pCur++;
  546. vStr = Vec_StrStart( Gia_AigerReadInt(pCur) ); pCur += 4;
  547. memcpy( Vec_StrArray(vStr), pCur, Vec_StrSize(vStr) );
  548. pCur += Vec_StrSize(vStr);
  549. pNew->pManTime = Tim_ManLoad( vStr, 1 );
  550. Vec_StrFree( vStr );
  551. fHieOnly = 1;
  552. if ( fVerbose ) printf( "Finished reading extension \"h\".\n" );
  553. }
  554. // read packing
  555. else if ( *pCur == 'k' )
  556. {
  557. extern Vec_Int_t * Gia_AigerReadPacking( unsigned char ** ppPos, int nSize );
  558. int nSize;
  559. pCur++;
  560. nSize = Gia_AigerReadInt(pCur);
  561. pCurTemp = pCur + nSize + 4; pCur += 4;
  562. pNew->vPacking = Gia_AigerReadPacking( &pCur, nSize );
  563. assert( pCur == pCurTemp );
  564. if ( fVerbose ) printf( "Finished reading extension \"k\".\n" );
  565. }
  566. // read mapping
  567. else if ( *pCur == 'm' )
  568. {
  569. extern int * Gia_AigerReadMapping( unsigned char ** ppPos, int nSize );
  570. extern int * Gia_AigerReadMappingSimple( unsigned char ** ppPos, int nSize );
  571. extern Vec_Int_t * Gia_AigerReadMappingDoc( unsigned char ** ppPos, int nObjs );
  572. int nSize;
  573. pCur++;
  574. nSize = Gia_AigerReadInt(pCur);
  575. pCurTemp = pCur + nSize + 4; pCur += 4;
  576. pNew->vMapping = Gia_AigerReadMappingDoc( &pCur, Gia_ManObjNum(pNew) );
  577. assert( pCur == pCurTemp );
  578. if ( fVerbose ) printf( "Finished reading extension \"m\".\n" );
  579. }
  580. // read model name
  581. else if ( *pCur == 'n' )
  582. {
  583. pCur++;
  584. if ( (*pCur >= 'a' && *pCur <= 'z') || (*pCur >= 'A' && *pCur <= 'Z') || (*pCur >= '0' && *pCur <= '9') )
  585. {
  586. pNew->pName = Abc_UtilStrsav( (char *)pCur ); pCur += strlen(pNew->pName) + 1;
  587. }
  588. else
  589. {
  590. pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
  591. ABC_FREE( pNew->pName );
  592. pNew->pName = Abc_UtilStrsav( (char *)pCur ); pCur += strlen(pNew->pName) + 1;
  593. assert( pCur == pCurTemp );
  594. }
  595. }
  596. // read placement
  597. else if ( *pCur == 'p' )
  598. {
  599. Gia_Plc_t * pPlacement;
  600. pCur++;
  601. pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
  602. pPlacement = ABC_ALLOC( Gia_Plc_t, Gia_ManObjNum(pNew) );
  603. memcpy( pPlacement, pCur, 4*Gia_ManObjNum(pNew) ); pCur += 4*Gia_ManObjNum(pNew);
  604. assert( pCur == pCurTemp );
  605. pNew->pPlacement = pPlacement;
  606. if ( fVerbose ) printf( "Finished reading extension \"p\".\n" );
  607. }
  608. // read register classes
  609. else if ( *pCur == 'r' )
  610. {
  611. int i, nRegs;
  612. pCur++;
  613. pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
  614. nRegs = Gia_AigerReadInt(pCur); pCur += 4;
  615. //nRegs = (pCurTemp - pCur)/4;
  616. pNew->vRegClasses = Vec_IntAlloc( nRegs );
  617. for ( i = 0; i < nRegs; i++ )
  618. Vec_IntPush( pNew->vRegClasses, Gia_AigerReadInt(pCur) ), pCur += 4;
  619. assert( pCur == pCurTemp );
  620. if ( fVerbose ) printf( "Finished reading extension \"r\".\n" );
  621. }
  622. // read register inits
  623. else if ( *pCur == 's' )
  624. {
  625. int i, nRegs;
  626. pCur++;
  627. pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
  628. nRegs = Gia_AigerReadInt(pCur); pCur += 4;
  629. pNew->vRegInits = Vec_IntAlloc( nRegs );
  630. for ( i = 0; i < nRegs; i++ )
  631. Vec_IntPush( pNew->vRegInits, Gia_AigerReadInt(pCur) ), pCur += 4;
  632. assert( pCur == pCurTemp );
  633. if ( fVerbose ) printf( "Finished reading extension \"s\".\n" );
  634. }
  635. // read configuration data
  636. else if ( *pCur == 'b' )
  637. {
  638. int nSize;
  639. pCur++;
  640. nSize = Gia_AigerReadInt(pCur);
  641. pCurTemp = pCur + nSize + 4; pCur += 4;
  642. pNew->pCellStr = Abc_UtilStrsav( (char*)pCur ); pCur += strlen((char*)pCur) + 1;
  643. nSize = nSize - strlen(pNew->pCellStr) - 1;
  644. assert( nSize % 4 == 0 );
  645. pNew->vConfigs = Vec_IntAlloc(nSize / 4);
  646. // memcpy(Vec_IntArray(pNew->vConfigs), pCur, nSize); pCur += nSize;
  647. for ( i = 0; i < nSize / 4; i++ )
  648. Vec_IntPush( pNew->vConfigs, Gia_AigerReadInt(pCur) ), pCur += 4;
  649. assert( pCur == pCurTemp );
  650. if ( fVerbose ) printf( "Finished reading extension \"b\".\n" );
  651. }
  652. // read choices
  653. else if ( *pCur == 'q' )
  654. {
  655. int i, nPairs, iRepr, iNode;
  656. assert( !Gia_ManHasChoices(pNew) );
  657. pNew->pSibls = ABC_CALLOC( int, Gia_ManObjNum(pNew) );
  658. pCur++;
  659. pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
  660. nPairs = Gia_AigerReadInt(pCur); pCur += 4;
  661. for ( i = 0; i < nPairs; i++ )
  662. {
  663. iRepr = Gia_AigerReadInt(pCur); pCur += 4;
  664. iNode = Gia_AigerReadInt(pCur); pCur += 4;
  665. pNew->pSibls[iRepr] = iNode;
  666. assert( iRepr > iNode );
  667. }
  668. assert( pCur == pCurTemp );
  669. if ( fVerbose ) printf( "Finished reading extension \"q\".\n" );
  670. }
  671. // read switching activity
  672. else if ( *pCur == 'u' )
  673. {
  674. unsigned char * pSwitching;
  675. pCur++;
  676. pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
  677. pSwitching = ABC_ALLOC( unsigned char, Gia_ManObjNum(pNew) );
  678. memcpy( pSwitching, pCur, Gia_ManObjNum(pNew) ); pCur += Gia_ManObjNum(pNew);
  679. assert( pCur == pCurTemp );
  680. if ( fVerbose ) printf( "Finished reading extension \"s\".\n" );
  681. }
  682. // read timing manager
  683. else if ( *pCur == 't' )
  684. {
  685. pCur++;
  686. vStr = Vec_StrStart( Gia_AigerReadInt(pCur) ); pCur += 4;
  687. memcpy( Vec_StrArray(vStr), pCur, Vec_StrSize(vStr) ); pCur += Vec_StrSize(vStr);
  688. pNew->pManTime = Tim_ManLoad( vStr, 0 );
  689. Vec_StrFree( vStr );
  690. if ( fVerbose ) printf( "Finished reading extension \"t\".\n" );
  691. }
  692. // read object classes
  693. else if ( *pCur == 'v' )
  694. {
  695. pCur++;
  696. pNew->vObjClasses = Vec_IntStart( Gia_AigerReadInt(pCur)/4 ); pCur += 4;
  697. memcpy( Vec_IntArray(pNew->vObjClasses), pCur, 4*Vec_IntSize(pNew->vObjClasses) );
  698. pCur += 4*Vec_IntSize(pNew->vObjClasses);
  699. if ( fVerbose ) printf( "Finished reading extension \"v\".\n" );
  700. }
  701. // read edge information
  702. else if ( *pCur == 'w' )
  703. {
  704. Vec_Int_t * vPairs;
  705. int i, nPairs;
  706. pCur++;
  707. pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
  708. nPairs = Gia_AigerReadInt(pCur); pCur += 4;
  709. vPairs = Vec_IntAlloc( 2*nPairs );
  710. for ( i = 0; i < 2*nPairs; i++ )
  711. Vec_IntPush( vPairs, Gia_AigerReadInt(pCur) ), pCur += 4;
  712. assert( pCur == pCurTemp );
  713. if ( fSkipStrash )
  714. {
  715. Gia_ManEdgeFromArray( pNew, vPairs );
  716. if ( fVerbose ) printf( "Finished reading extension \"w\".\n" );
  717. }
  718. else
  719. printf( "Cannot read extension \"w\" because AIG is rehashed. Use \"&r -s <file.aig>\".\n" );
  720. Vec_IntFree( vPairs );
  721. }
  722. else break;
  723. }
  724. }
  725. // skipping the comments
  726. Vec_IntFree( vNodes );
  727. // update polarity of the additional outputs
  728. if ( nBad || nConstr || nJust || nFair )
  729. Gia_ManInvertConstraints( pNew );
  730. // clean the PO drivers
  731. if ( vPoTypes )
  732. {
  733. pNew = Gia_ManDupWithConstraints( pTemp = pNew, vPoTypes );
  734. Gia_ManStop( pTemp );
  735. Vec_IntFreeP( &vPoTypes );
  736. }
  737. if ( !fGiaSimple && !fSkipStrash && Gia_ManHasDangling(pNew) )
  738. {
  739. Tim_Man_t * pManTime;
  740. Vec_Int_t * vFlopMap, * vGateMap, * vObjMap;
  741. vFlopMap = pNew->vFlopClasses; pNew->vFlopClasses = NULL;
  742. vGateMap = pNew->vGateClasses; pNew->vGateClasses = NULL;
  743. vObjMap = pNew->vObjClasses; pNew->vObjClasses = NULL;
  744. pManTime = (Tim_Man_t *)pNew->pManTime; pNew->pManTime = NULL;
  745. pNew = Gia_ManCleanup( pTemp = pNew );
  746. if ( (vGateMap || vObjMap) && (Gia_ManObjNum(pNew) < Gia_ManObjNum(pTemp)) )
  747. printf( "Cleanup removed objects after reading. Old gate/object abstraction maps are invalid!\n" );
  748. Gia_ManStop( pTemp );
  749. pNew->vFlopClasses = vFlopMap;
  750. pNew->vGateClasses = vGateMap;
  751. pNew->vObjClasses = vObjMap;
  752. pNew->pManTime = pManTime;
  753. }
  754. if ( fHieOnly )
  755. {
  756. // Tim_ManPrint( (Tim_Man_t *)pNew->pManTime );
  757. if ( Abc_FrameReadLibBox() == NULL )
  758. printf( "Warning: Creating unit-delay box delay tables because box library is not available.\n" );
  759. Tim_ManCreate( (Tim_Man_t *)pNew->pManTime, Abc_FrameReadLibBox(), pNew->vInArrs, pNew->vOutReqs );
  760. }
  761. Vec_FltFreeP( &pNew->vInArrs );
  762. Vec_FltFreeP( &pNew->vOutReqs );
  763. /*
  764. // check the result
  765. if ( fCheck && !Gia_ManCheck( pNew ) )
  766. {
  767. printf( "Gia_AigerRead: The network check has failed.\n" );
  768. Gia_ManStop( pNew );
  769. return NULL;
  770. }
  771. */
  772. if ( vInits && Vec_IntSum(vInits) )
  773. {
  774. char * pInit = ABC_ALLOC( char, Vec_IntSize(vInits) + 1 );
  775. Gia_Obj_t * pObj;
  776. int i;
  777. assert( Vec_IntSize(vInits) == Gia_ManRegNum(pNew) );
  778. Gia_ManForEachRo( pNew, pObj, i )
  779. {
  780. if ( Vec_IntEntry(vInits, i) == 0 )
  781. pInit[i] = '0';
  782. else if ( Vec_IntEntry(vInits, i) == 1 )
  783. pInit[i] = '1';
  784. else
  785. {
  786. assert( Vec_IntEntry(vInits, i) == Abc_Var2Lit(Gia_ObjId(pNew, pObj), 0) );
  787. // unitialized value of the latch is the latch literal according to http://fmv.jku.at/hwmcc11/beyond1.pdf
  788. pInit[i] = 'X';
  789. }
  790. }
  791. pInit[i] = 0;
  792. pNew = Gia_ManDupZeroUndc( pTemp = pNew, pInit, fGiaSimple, 1 );
  793. pNew->nConstrs = pTemp->nConstrs; pTemp->nConstrs = 0;
  794. Gia_ManStop( pTemp );
  795. ABC_FREE( pInit );
  796. }
  797. Vec_IntFreeP( &vInits );
  798. if ( !fGiaSimple && !fSkipStrash && pNew->vMapping )
  799. {
  800. Abc_Print( 0, "Structural hashing enabled while reading AIGER invalidated the mapping. Consider using \"&r -s\".\n" );
  801. Vec_IntFreeP( &pNew->vMapping );
  802. }
  803. return pNew;
  804. }
  805. /**Function*************************************************************
  806. Synopsis [Reads the AIG in the binary AIGER format.]
  807. Description []
  808. SideEffects []
  809. SeeAlso []
  810. ***********************************************************************/
  811. Gia_Man_t * Gia_AigerRead( char * pFileName, int fGiaSimple, int fSkipStrash, int fCheck )
  812. {
  813. FILE * pFile;
  814. Gia_Man_t * pNew;
  815. char * pName, * pContents;
  816. int nFileSize;
  817. int RetValue;
  818. // read the file into the buffer
  819. Gia_FileFixName( pFileName );
  820. nFileSize = Gia_FileSize( pFileName );
  821. pFile = fopen( pFileName, "rb" );
  822. pContents = ABC_ALLOC( char, nFileSize );
  823. RetValue = fread( pContents, nFileSize, 1, pFile );
  824. fclose( pFile );
  825. pNew = Gia_AigerReadFromMemory( pContents, nFileSize, fGiaSimple, fSkipStrash, fCheck );
  826. ABC_FREE( pContents );
  827. if ( pNew )
  828. {
  829. ABC_FREE( pNew->pName );
  830. pName = Gia_FileNameGeneric( pFileName );
  831. pNew->pName = Abc_UtilStrsav( pName );
  832. ABC_FREE( pName );
  833. assert( pNew->pSpec == NULL );
  834. pNew->pSpec = Abc_UtilStrsav( pFileName );
  835. }
  836. return pNew;
  837. }
  838. /**Function*************************************************************
  839. Synopsis [Writes the AIG in into the memory buffer.]
  840. Description [The resulting buffer constains the AIG in AIGER format.
  841. The resulting buffer should be deallocated by the user.]
  842. SideEffects []
  843. SeeAlso []
  844. ***********************************************************************/
  845. Vec_Str_t * Gia_AigerWriteIntoMemoryStr( Gia_Man_t * p )
  846. {
  847. Vec_Str_t * vBuffer;
  848. Gia_Obj_t * pObj;
  849. int nNodes = 0, i, uLit, uLit0, uLit1;
  850. // set the node numbers to be used in the output file
  851. Gia_ManConst0(p)->Value = nNodes++;
  852. Gia_ManForEachCi( p, pObj, i )
  853. pObj->Value = nNodes++;
  854. Gia_ManForEachAnd( p, pObj, i )
  855. pObj->Value = nNodes++;
  856. // write the header "M I L O A" where M = I + L + A
  857. vBuffer = Vec_StrAlloc( 3*Gia_ManObjNum(p) );
  858. Vec_StrPrintStr( vBuffer, "aig " );
  859. Vec_StrPrintNum( vBuffer, Gia_ManCandNum(p) );
  860. Vec_StrPrintStr( vBuffer, " " );
  861. Vec_StrPrintNum( vBuffer, Gia_ManPiNum(p) );
  862. Vec_StrPrintStr( vBuffer, " " );
  863. Vec_StrPrintNum( vBuffer, Gia_ManRegNum(p) );
  864. Vec_StrPrintStr( vBuffer, " " );
  865. Vec_StrPrintNum( vBuffer, Gia_ManPoNum(p) );
  866. Vec_StrPrintStr( vBuffer, " " );
  867. Vec_StrPrintNum( vBuffer, Gia_ManAndNum(p) );
  868. Vec_StrPrintStr( vBuffer, "\n" );
  869. // write latch drivers
  870. Gia_ManForEachRi( p, pObj, i )
  871. {
  872. uLit = Abc_Var2Lit( Gia_ObjValue(Gia_ObjFanin0(pObj)), Gia_ObjFaninC0(pObj) );
  873. Vec_StrPrintNum( vBuffer, uLit );
  874. Vec_StrPrintStr( vBuffer, "\n" );
  875. }
  876. // write PO drivers
  877. Gia_ManForEachPo( p, pObj, i )
  878. {
  879. uLit = Abc_Var2Lit( Gia_ObjValue(Gia_ObjFanin0(pObj)), Gia_ObjFaninC0(pObj) );
  880. Vec_StrPrintNum( vBuffer, uLit );
  881. Vec_StrPrintStr( vBuffer, "\n" );
  882. }
  883. // write the nodes into the buffer
  884. Gia_ManForEachAnd( p, pObj, i )
  885. {
  886. uLit = Abc_Var2Lit( Gia_ObjValue(pObj), 0 );
  887. uLit0 = Abc_Var2Lit( Gia_ObjValue(Gia_ObjFanin0(pObj)), Gia_ObjFaninC0(pObj) );
  888. uLit1 = Abc_Var2Lit( Gia_ObjValue(Gia_ObjFanin1(pObj)), Gia_ObjFaninC1(pObj) );
  889. assert( uLit0 != uLit1 );
  890. if ( uLit0 > uLit1 )
  891. {
  892. int Temp = uLit0;
  893. uLit0 = uLit1;
  894. uLit1 = Temp;
  895. }
  896. Gia_AigerWriteUnsigned( vBuffer, uLit - uLit1 );
  897. Gia_AigerWriteUnsigned( vBuffer, uLit1 - uLit0 );
  898. }
  899. Vec_StrPrintStr( vBuffer, "c" );
  900. return vBuffer;
  901. }
  902. /**Function*************************************************************
  903. Synopsis [Writes the AIG in into the memory buffer.]
  904. Description [The resulting buffer constains the AIG in AIGER format.
  905. The CI/CO/AND nodes are assumed to be ordered according to some rule.
  906. The resulting buffer should be deallocated by the user.]
  907. SideEffects [Note that in vCos, PIs are order first, followed by latches!]
  908. SeeAlso []
  909. ***********************************************************************/
  910. Vec_Str_t * Gia_AigerWriteIntoMemoryStrPart( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, int nRegs )
  911. {
  912. Vec_Str_t * vBuffer;
  913. Gia_Obj_t * pObj;
  914. int nNodes = 0, i, uLit, uLit0, uLit1;
  915. // set the node numbers to be used in the output file
  916. Gia_ManConst0(p)->Value = nNodes++;
  917. Gia_ManForEachObjVec( vCis, p, pObj, i )
  918. {
  919. assert( Gia_ObjIsCi(pObj) );
  920. pObj->Value = nNodes++;
  921. }
  922. Gia_ManForEachObjVec( vAnds, p, pObj, i )
  923. {
  924. assert( Gia_ObjIsAnd(pObj) );
  925. pObj->Value = nNodes++;
  926. }
  927. // write the header "M I L O A" where M = I + L + A
  928. vBuffer = Vec_StrAlloc( 3*Gia_ManObjNum(p) );
  929. Vec_StrPrintStr( vBuffer, "aig " );
  930. Vec_StrPrintNum( vBuffer, Vec_IntSize(vCis) + Vec_IntSize(vAnds) );
  931. Vec_StrPrintStr( vBuffer, " " );
  932. Vec_StrPrintNum( vBuffer, Vec_IntSize(vCis) - nRegs );
  933. Vec_StrPrintStr( vBuffer, " " );
  934. Vec_StrPrintNum( vBuffer, nRegs );
  935. Vec_StrPrintStr( vBuffer, " " );
  936. Vec_StrPrintNum( vBuffer, Vec_IntSize(vCos) - nRegs );
  937. Vec_StrPrintStr( vBuffer, " " );
  938. Vec_StrPrintNum( vBuffer, Vec_IntSize(vAnds) );
  939. Vec_StrPrintStr( vBuffer, "\n" );
  940. // write latch drivers
  941. Gia_ManForEachObjVec( vCos, p, pObj, i )
  942. {
  943. assert( Gia_ObjIsCo(pObj) );
  944. if ( i < Vec_IntSize(vCos) - nRegs )
  945. continue;
  946. uLit = Abc_Var2Lit( Gia_ObjValue(Gia_ObjFanin0(pObj)), Gia_ObjFaninC0(pObj) );
  947. Vec_StrPrintNum( vBuffer, uLit );
  948. Vec_StrPrintStr( vBuffer, "\n" );
  949. }
  950. // write output drivers
  951. Gia_ManForEachObjVec( vCos, p, pObj, i )
  952. {
  953. assert( Gia_ObjIsCo(pObj) );
  954. if ( i >= Vec_IntSize(vCos) - nRegs )
  955. continue;
  956. uLit = Abc_Var2Lit( Gia_ObjValue(Gia_ObjFanin0(pObj)), Gia_ObjFaninC0(pObj) );
  957. Vec_StrPrintNum( vBuffer, uLit );
  958. Vec_StrPrintStr( vBuffer, "\n" );
  959. }
  960. // write the nodes into the buffer
  961. Gia_ManForEachObjVec( vAnds, p, pObj, i )
  962. {
  963. uLit = Abc_Var2Lit( Gia_ObjValue(pObj), 0 );
  964. uLit0 = Abc_Var2Lit( Gia_ObjValue(Gia_ObjFanin0(pObj)), Gia_ObjFaninC0(pObj) );
  965. uLit1 = Abc_Var2Lit( Gia_ObjValue(Gia_ObjFanin1(pObj)), Gia_ObjFaninC1(pObj) );
  966. assert( uLit0 != uLit1 );
  967. if ( uLit0 > uLit1 )
  968. {
  969. int Temp = uLit0;
  970. uLit0 = uLit1;
  971. uLit1 = Temp;
  972. }
  973. Gia_AigerWriteUnsigned( vBuffer, uLit - uLit1 );
  974. Gia_AigerWriteUnsigned( vBuffer, uLit1 - uLit0 );
  975. }
  976. Vec_StrPrintStr( vBuffer, "c" );
  977. return vBuffer;
  978. }
  979. /**Function*************************************************************
  980. Synopsis [Writes the AIG in the binary AIGER format.]
  981. Description []
  982. SideEffects []
  983. SeeAlso []
  984. ***********************************************************************/
  985. void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact )
  986. {
  987. int fVerbose = XAIG_VERBOSE;
  988. FILE * pFile;
  989. Gia_Man_t * p;
  990. Gia_Obj_t * pObj;
  991. Vec_Str_t * vStrExt;
  992. int i, nBufferSize, Pos;
  993. unsigned char * pBuffer;
  994. unsigned uLit0, uLit1, uLit;
  995. assert( pInit->nXors == 0 && pInit->nMuxes == 0 );
  996. if ( Gia_ManCoNum(pInit) == 0 )
  997. {
  998. printf( "AIG cannot be written because it has no POs.\n" );
  999. return;
  1000. }
  1001. // start the output stream
  1002. pFile = fopen( pFileName, "wb" );
  1003. if ( pFile == NULL )
  1004. {
  1005. fprintf( stdout, "Gia_AigerWrite(): Cannot open the output file \"%s\".\n", pFileName );
  1006. return;
  1007. }
  1008. // create normalized AIG
  1009. if ( !Gia_ManIsNormalized(pInit) )
  1010. {
  1011. // printf( "Gia_AigerWrite(): Normalizing AIG for writing.\n" );
  1012. p = Gia_ManDupNormalize( pInit, 0 );
  1013. Gia_ManTransferMapping( p, pInit );
  1014. Gia_ManTransferPacking( p, pInit );
  1015. Gia_ManTransferTiming( p, pInit );
  1016. p->vNamesIn = pInit->vNamesIn; pInit->vNamesIn = NULL;
  1017. p->vNamesOut = pInit->vNamesOut; pInit->vNamesOut = NULL;
  1018. p->nConstrs = pInit->nConstrs; pInit->nConstrs = 0;
  1019. }
  1020. else
  1021. p = pInit;
  1022. // write the header "M I L O A" where M = I + L + A
  1023. fprintf( pFile, "aig%s %u %u %u %u %u",
  1024. fCompact? "2" : "",
  1025. Gia_ManCiNum(p) + Gia_ManAndNum(p),
  1026. Gia_ManPiNum(p),
  1027. Gia_ManRegNum(p),
  1028. Gia_ManConstrNum(p) ? 0 : Gia_ManPoNum(p),
  1029. Gia_ManAndNum(p) );
  1030. // write the extended header "B C J F"
  1031. if ( Gia_ManConstrNum(p) )
  1032. fprintf( pFile, " %u %u", Gia_ManPoNum(p) - Gia_ManConstrNum(p), Gia_ManConstrNum(p) );
  1033. fprintf( pFile, "\n" );
  1034. Gia_ManInvertConstraints( p );
  1035. if ( !fCompact )
  1036. {
  1037. // write latch drivers
  1038. Gia_ManForEachRi( p, pObj, i )
  1039. fprintf( pFile, "%u\n", Gia_ObjFaninLit0p(p, pObj) );
  1040. // write PO drivers
  1041. Gia_ManForEachPo( p, pObj, i )
  1042. fprintf( pFile, "%u\n", Gia_ObjFaninLit0p(p, pObj) );
  1043. }
  1044. else
  1045. {
  1046. Vec_Int_t * vLits = Gia_AigerCollectLiterals( p );
  1047. Vec_Str_t * vBinary = Gia_AigerWriteLiterals( vLits );
  1048. fwrite( Vec_StrArray(vBinary), 1, Vec_StrSize(vBinary), pFile );
  1049. Vec_StrFree( vBinary );
  1050. Vec_IntFree( vLits );
  1051. }
  1052. Gia_ManInvertConstraints( p );
  1053. // write the nodes into the buffer
  1054. Pos = 0;
  1055. nBufferSize = 8 * Gia_ManAndNum(p) + 100; // skeptically assuming 3 chars per one AIG edge
  1056. pBuffer = ABC_ALLOC( unsigned char, nBufferSize );
  1057. Gia_ManForEachAnd( p, pObj, i )
  1058. {
  1059. uLit = Abc_Var2Lit( i, 0 );
  1060. uLit0 = Gia_ObjFaninLit0( pObj, i );
  1061. uLit1 = Gia_ObjFaninLit1( pObj, i );
  1062. assert( p->fGiaSimple || Gia_ManBufNum(p) || uLit0 < uLit1 );
  1063. Pos = Gia_AigerWriteUnsignedBuffer( pBuffer, Pos, uLit - uLit1 );
  1064. Pos = Gia_AigerWriteUnsignedBuffer( pBuffer, Pos, uLit1 - uLit0 );
  1065. if ( Pos > nBufferSize - 10 )
  1066. {
  1067. printf( "Gia_AigerWrite(): AIGER generation has failed because the allocated buffer is too small.\n" );
  1068. fclose( pFile );
  1069. if ( p != pInit )
  1070. Gia_ManStop( p );
  1071. return;
  1072. }
  1073. }
  1074. assert( Pos < nBufferSize );
  1075. // write the buffer
  1076. fwrite( pBuffer, 1, Pos, pFile );
  1077. ABC_FREE( pBuffer );
  1078. // write the symbol table
  1079. if ( p->vNamesIn && p->vNamesOut )
  1080. {
  1081. assert( Vec_PtrSize(p->vNamesIn) == Gia_ManCiNum(p) );
  1082. assert( Vec_PtrSize(p->vNamesOut) == Gia_ManCoNum(p) );
  1083. // write PIs
  1084. Gia_ManForEachPi( p, pObj, i )
  1085. fprintf( pFile, "i%d %s\n", i, (char *)Vec_PtrEntry(p->vNamesIn, i) );
  1086. // write latches
  1087. Gia_ManForEachRo( p, pObj, i )
  1088. fprintf( pFile, "l%d %s\n", i, (char *)Vec_PtrEntry(p->vNamesIn, Gia_ManPiNum(p) + i) );
  1089. // write POs
  1090. Gia_ManForEachPo( p, pObj, i )
  1091. fprintf( pFile, "o%d %s\n", i, (char *)Vec_PtrEntry(p->vNamesOut, i) );
  1092. }
  1093. // write the comment
  1094. // fprintf( pFile, "c\n" );
  1095. fprintf( pFile, "c" );
  1096. // write additional AIG
  1097. if ( p->pAigExtra )
  1098. {
  1099. fprintf( pFile, "a" );
  1100. vStrExt = Gia_AigerWriteIntoMemoryStr( p->pAigExtra );
  1101. Gia_FileWriteBufferSize( pFile, Vec_StrSize(vStrExt) );
  1102. fwrite( Vec_StrArray(vStrExt), 1, Vec_StrSize(vStrExt), pFile );
  1103. Vec_StrFree( vStrExt );
  1104. if ( fVerbose ) printf( "Finished writing extension \"a\".\n" );
  1105. }
  1106. // write constraints
  1107. if ( p->nConstrs )
  1108. {
  1109. fprintf( pFile, "c" );
  1110. Gia_FileWriteBufferSize( pFile, 4 );
  1111. Gia_FileWriteBufferSize( pFile, p->nConstrs );
  1112. }
  1113. // write timing information
  1114. if ( p->nAnd2Delay )
  1115. {
  1116. fprintf( pFile, "d" );
  1117. Gia_FileWriteBufferSize( pFile, 4 );
  1118. Gia_FileWriteBufferSize( pFile, p->nAnd2Delay );
  1119. }
  1120. if ( p->pManTime )
  1121. {
  1122. float * pTimes;
  1123. pTimes = Tim_ManGetArrTimes( (Tim_Man_t *)p->pManTime );
  1124. if ( pTimes )
  1125. {
  1126. fprintf( pFile, "i" );
  1127. Gia_FileWriteBufferSize( pFile, 4*Tim_ManPiNum((Tim_Man_t *)p->pManTime) );
  1128. fwrite( pTimes, 1, 4*Tim_ManPiNum((Tim_Man_t *)p->pManTime), pFile );
  1129. ABC_FREE( pTimes );
  1130. if ( fVerbose ) printf( "Finished writing extension \"i\".\n" );
  1131. }
  1132. pTimes = Tim_ManGetReqTimes( (Tim_Man_t *)p->pManTime );
  1133. if ( pTimes )
  1134. {
  1135. fprintf( pFile, "o" );
  1136. Gia_FileWriteBufferSize( pFile, 4*Tim_ManPoNum((Tim_Man_t *)p->pManTime) );
  1137. fwrite( pTimes, 1, 4*Tim_ManPoNum((Tim_Man_t *)p->pManTime), pFile );
  1138. ABC_FREE( pTimes );
  1139. if ( fVerbose ) printf( "Finished writing extension \"o\".\n" );
  1140. }
  1141. }
  1142. // write equivalences
  1143. if ( p->pReprs && p->pNexts )
  1144. {
  1145. extern Vec_Str_t * Gia_WriteEquivClasses( Gia_Man_t * p );
  1146. fprintf( pFile, "e" );
  1147. vStrExt = Gia_WriteEquivClasses( p );
  1148. Gia_FileWriteBufferSize( pFile, Vec_StrSize(vStrExt) );
  1149. fwrite( Vec_StrArray(vStrExt), 1, Vec_StrSize(vStrExt), pFile );
  1150. Vec_StrFree( vStrExt );
  1151. }
  1152. // write flop classes
  1153. if ( p->vFlopClasses )
  1154. {
  1155. fprintf( pFile, "f" );
  1156. Gia_FileWriteBufferSize( pFile, 4*Gia_ManRegNum(p) );
  1157. assert( Vec_IntSize(p->vFlopClasses) == Gia_ManRegNum(p) );
  1158. fwrite( Vec_IntArray(p->vFlopClasses), 1, 4*Gia_ManRegNum(p), pFile );
  1159. }
  1160. // write gate classes
  1161. if ( p->vGateClasses )
  1162. {
  1163. fprintf( pFile, "g" );
  1164. Gia_FileWriteBufferSize( pFile, 4*Gia_ManObjNum(p) );
  1165. assert( Vec_IntSize(p->vGateClasses) == Gia_ManObjNum(p) );
  1166. fwrite( Vec_IntArray(p->vGateClasses), 1, 4*Gia_ManObjNum(p), pFile );
  1167. }
  1168. // write hierarchy info
  1169. if ( p->pManTime )
  1170. {
  1171. fprintf( pFile, "h" );
  1172. vStrExt = Tim_ManSave( (Tim_Man_t *)p->pManTime, 1 );
  1173. Gia_FileWriteBufferSize( pFile, Vec_StrSize(vStrExt) );
  1174. fwrite( Vec_StrArray(vStrExt), 1, Vec_StrSize(vStrExt), pFile );
  1175. Vec_StrFree( vStrExt );
  1176. if ( fVerbose ) printf( "Finished writing extension \"h\".\n" );
  1177. }
  1178. // write packing
  1179. if ( p->vPacking )
  1180. {
  1181. extern Vec_Str_t * Gia_WritePacking( Vec_Int_t * vPacking );
  1182. fprintf( pFile, "k" );
  1183. vStrExt = Gia_WritePacking( p->vPacking );
  1184. Gia_FileWriteBufferSize( pFile, Vec_StrSize(vStrExt) );
  1185. fwrite( Vec_StrArray(vStrExt), 1, Vec_StrSize(vStrExt), pFile );
  1186. Vec_StrFree( vStrExt );
  1187. if ( fVerbose ) printf( "Finished writing extension \"k\".\n" );
  1188. }
  1189. // write edges
  1190. if ( p->vEdge1 )
  1191. {
  1192. Vec_Int_t * vPairs = Gia_ManEdgeToArray( p );
  1193. int i;
  1194. fprintf( pFile, "w" );
  1195. Gia_FileWriteBufferSize( pFile, 4*(Vec_IntSize(vPairs)+1) );
  1196. Gia_FileWriteBufferSize( pFile, Vec_IntSize(vPairs)/2 );
  1197. for ( i = 0; i < Vec_IntSize(vPairs); i++ )
  1198. Gia_FileWriteBufferSize( pFile, Vec_IntEntry(vPairs, i) );
  1199. Vec_IntFree( vPairs );
  1200. }
  1201. // write mapping
  1202. if ( Gia_ManHasMapping(p) )
  1203. {
  1204. extern Vec_Str_t * Gia_AigerWriteMapping( Gia_Man_t * p );
  1205. extern Vec_Str_t * Gia_AigerWriteMappingSimple( Gia_Man_t * p );
  1206. extern Vec_Str_t * Gia_AigerWriteMappingDoc( Gia_Man_t * p );
  1207. fprintf( pFile, "m" );
  1208. vStrExt = Gia_AigerWriteMappingDoc( p );
  1209. Gia_FileWriteBufferSize( pFile, Vec_StrSize(vStrExt) );
  1210. fwrite( Vec_StrArray(vStrExt), 1, Vec_StrSize(vStrExt), pFile );
  1211. Vec_StrFree( vStrExt );
  1212. if ( fVerbose ) printf( "Finished writing extension \"m\".\n" );
  1213. }
  1214. // write placement
  1215. if ( p->pPlacement )
  1216. {
  1217. fprintf( pFile, "p" );
  1218. Gia_FileWriteBufferSize( pFile, 4*Gia_ManObjNum(p) );
  1219. fwrite( p->pPlacement, 1, 4*Gia_ManObjNum(p), pFile );
  1220. }
  1221. // write register classes
  1222. if ( p->vRegClasses )
  1223. {
  1224. int i;

Large files files are truncated, but you can click here to view the full file