@@ -1292,12 +1292,201 @@ static void GiaHie_DumpInterfaceAssigns( Gia_Man_t * p, char * pFileName )
12921292 fclose ( pFile );
12931293}
12941294
1295+ /**Function*************************************************************
1296+
1297+ Synopsis [Dumps mapped AIG as LUT6 instances in Verilog]
1298+
1299+ Description []
1300+
1301+ SideEffects []
1302+
1303+ SeeAlso []
1304+
1305+ ***********************************************************************/
1306+ static void GiaHie_DumpMappedLuts ( Gia_Man_t * p , char * pFileName )
1307+ {
1308+ int i , k , iFanin , nLutSize , nDigits ;
1309+ FILE * pFile ;
1310+ Vec_Int_t * vLeaves ;
1311+ word * pTruth ;
1312+ Gia_Obj_t * pObj ;
1313+
1314+ // Check if AIG is mapped
1315+ if ( !Gia_ManHasMapping (p ) )
1316+ {
1317+ printf ( "Cannot write LUT-based Verilog because AIG is not mapped.\n" );
1318+ return ;
1319+ }
1320+
1321+ pFile = fopen ( pFileName , "wb" );
1322+ if ( pFile == NULL )
1323+ {
1324+ printf ( "Cannot open output file \"%s\".\n" , pFileName );
1325+ return ;
1326+ }
1327+
1328+ nDigits = Abc_Base10Log ( Gia_ManObjNum (p ) );
1329+ if ( nDigits < 3 )
1330+ nDigits = 3 ;
1331+
1332+ // Write header
1333+ fprintf ( pFile , "`timescale 1ns/1ps\n\n" );
1334+
1335+ // Write LUT module definitions for Yosys compatibility (compact version)
1336+ fprintf ( pFile , "module LUT2 #( parameter INIT = 04\'h0 ) ( output O, input I0, I1 );\n" );
1337+ fprintf ( pFile , " assign O = INIT[ {I1, I0} ];\n" );
1338+ fprintf ( pFile , "endmodule\n" );
1339+
1340+ fprintf ( pFile , "module LUT3 #( parameter INIT = 08\'h0 ) ( output O, input I0, I1, I2 );\n" );
1341+ fprintf ( pFile , " assign O = INIT[ {I2, I1, I0} ];\n" );
1342+ fprintf ( pFile , "endmodule\n" );
1343+
1344+ fprintf ( pFile , "module LUT4 #( parameter INIT = 16\'h0 ) ( output O, input I0, I1, I2, I3 );\n" );
1345+ fprintf ( pFile , " assign O = INIT[ {I3, I2, I1, I0} ];\n" );
1346+ fprintf ( pFile , "endmodule\n" );
1347+
1348+ fprintf ( pFile , "module LUT5 #( parameter INIT = 32\'h0 ) ( output O, input I0, I1, I2, I3, I4 );\n" );
1349+ fprintf ( pFile , " assign O = INIT[ {I4, I3, I2, I1, I0} ];\n" );
1350+ fprintf ( pFile , "endmodule\n" );
1351+
1352+ fprintf ( pFile , "module LUT6 #( parameter INIT = 64\'h0 ) ( output O, input I0, I1, I2, I3, I4, I5 );\n" );
1353+ fprintf ( pFile , " assign O = INIT[ {I5, I4, I3, I2, I1, I0} ];\n" );
1354+ fprintf ( pFile , "endmodule\n\n" );
1355+
1356+ // Write main module
1357+ fprintf ( pFile , "module " );
1358+ GiaHie_DumpModuleName ( pFile , p -> pName );
1359+ fprintf ( pFile , " (\n" );
1360+ GiaHie_DumpPortDecls ( p , pFile );
1361+ fprintf ( pFile , "\n);\n\n" );
1362+
1363+ // Declare wires for inputs (using object IDs like regular &write_ver)
1364+ if ( Gia_ManCiNum (p ) )
1365+ {
1366+ fprintf ( pFile , " wire " );
1367+ GiaHie_WriteObjRange ( pFile , p , 0 , Gia_ManCiNum (p ), nDigits , 7 , 4 , 0 , 1 );
1368+ fprintf ( pFile , ";\n\n" );
1369+ GiaHie_DumpInputAssigns ( p , pFile , nDigits );
1370+ fprintf ( pFile , "\n" );
1371+ }
1372+
1373+ // Declare wires for outputs (using object IDs like regular &write_ver)
1374+ if ( Gia_ManCoNum (p ) )
1375+ {
1376+ fprintf ( pFile , " wire " );
1377+ GiaHie_WriteObjRange ( pFile , p , 0 , Gia_ManCoNum (p ), nDigits , 7 , 4 , 0 , 0 );
1378+ fprintf ( pFile , ";\n\n" );
1379+ GiaHie_DumpOutputAssigns ( p , pFile , nDigits );
1380+ fprintf ( pFile , "\n" );
1381+ }
1382+
1383+ // Declare internal wires for LUT outputs (10 per line)
1384+ {
1385+ int nWiresPerLine = 10 ;
1386+ int nWireCount = 0 ;
1387+ int fFirst = 1 ;
1388+ Gia_ManForEachLut ( p , i )
1389+ {
1390+ if ( nWireCount == 0 )
1391+ fprintf ( pFile , " wire " );
1392+ if ( !fFirst )
1393+ fprintf ( pFile , ", " );
1394+ fprintf ( pFile , "n%0*d" , nDigits , i );
1395+ fFirst = 0 ;
1396+ nWireCount ++ ;
1397+ if ( nWireCount == nWiresPerLine )
1398+ {
1399+ fprintf ( pFile , ";\n" );
1400+ nWireCount = 0 ;
1401+ fFirst = 1 ;
1402+ }
1403+ }
1404+ if ( nWireCount > 0 )
1405+ fprintf ( pFile , ";\n" );
1406+ }
1407+ fprintf ( pFile , "\n" );
1408+
1409+ // Initialize truth table computation
1410+ vLeaves = Vec_IntAlloc ( 6 );
1411+ Gia_ObjComputeTruthTableStart ( p , 6 );
1412+
1413+ // Write LUT6 instances
1414+ Gia_ManForEachLut ( p , i )
1415+ {
1416+ nLutSize = Gia_ObjLutSize ( p , i );
1417+
1418+ // Collect LUT inputs
1419+ Vec_IntClear ( vLeaves );
1420+ Gia_LutForEachFanin ( p , i , iFanin , k )
1421+ Vec_IntPush ( vLeaves , iFanin );
1422+
1423+ // Compute truth table
1424+ pTruth = Gia_ObjComputeTruthTableCut ( p , Gia_ManObj (p , i ), vLeaves );
1425+
1426+ // Write LUT instance - use appropriate size LUT based on inputs
1427+ if ( nLutSize <= 1 )
1428+ nLutSize = 2 ; // minimum LUT size is 2
1429+
1430+ // Determine INIT width and padding
1431+ int nInitBits = (1 << nLutSize );
1432+ unsigned long long truthValue = (nLutSize <= 6 ) ? pTruth [0 ] : 0 ;
1433+
1434+ // Mask truth value to the appropriate number of bits
1435+ if ( nLutSize < 6 )
1436+ truthValue &= ((1ULL << nInitBits ) - 1 );
1437+
1438+ // Write LUT instance with padding for alignment
1439+ fprintf ( pFile , " (* DONT_TOUCH = \"yes\" *) LUT%d #(" , nLutSize );
1440+
1441+ // Write INIT parameter with appropriate width and padding aligned to 64-bit width
1442+ if ( nLutSize == 2 )
1443+ fprintf ( pFile , ".INIT(04'h%01llx )) u_lut%0*d (" , truthValue , nDigits , i );
1444+ else if ( nLutSize == 3 )
1445+ fprintf ( pFile , ".INIT(08'h%02llx )) u_lut%0*d (" , truthValue , nDigits , i );
1446+ else if ( nLutSize == 4 )
1447+ fprintf ( pFile , ".INIT(16'h%04llx )) u_lut%0*d (" , truthValue , nDigits , i );
1448+ else if ( nLutSize == 5 )
1449+ fprintf ( pFile , ".INIT(32'h%08llx )) u_lut%0*d (" , truthValue , nDigits , i );
1450+ else // nLutSize == 6
1451+ fprintf ( pFile , ".INIT(64'h%016llx)) u_lut%0*d (" , truthValue , nDigits , i );
1452+
1453+ // Write LUT inputs - only the ones actually used by this LUT size
1454+ for ( k = 0 ; k < nLutSize ; k ++ )
1455+ {
1456+ iFanin = Vec_IntEntry ( vLeaves , k );
1457+ if ( k > 0 )
1458+ fprintf ( pFile , ", " );
1459+ fprintf ( pFile , ".I%d(n%0*d)" , k , nDigits , iFanin );
1460+ }
1461+
1462+ // Write LUT output
1463+ fprintf ( pFile , ", .O(n%0*d));\n" , nDigits , i );
1464+ }
1465+
1466+ // Cleanup truth table computation
1467+ Gia_ObjComputeTruthTableStop ( p );
1468+ Vec_IntFree ( vLeaves );
1469+
1470+ fprintf ( pFile , "\n" );
1471+
1472+ // Connect internal nodes to outputs (like regular &write_ver)
1473+ Gia_ManForEachCo ( p , pObj , i )
1474+ {
1475+ fprintf ( pFile , " assign n%0*d = " , nDigits , Gia_ManCoIdToId (p , i ) );
1476+ GiaHie_PrintObjLit ( pFile , Gia_ObjFaninId0p (p , pObj ), Gia_ObjFaninC0 (pObj ), nDigits );
1477+ fprintf ( pFile , ";\n" );
1478+ }
1479+
1480+ fprintf ( pFile , "\nendmodule\n" );
1481+ fclose ( pFile );
1482+ }
1483+
12951484/**Function*************************************************************
12961485
12971486 Synopsis []
12981487
12991488 Description []
1300-
1489+
13011490 SideEffects []
13021491
13031492 SeeAlso []
@@ -1314,6 +1503,30 @@ void Gia_WriteVerilog( char * pFileName, Gia_Man_t * pGia, int fUseGates, int fV
13141503 GiaHie_DumpInterfaceAssigns ( pGia , pFileName );
13151504}
13161505
1506+ /**Function*************************************************************
1507+
1508+ Synopsis [Writes mapped AIG as LUT6-based Verilog]
1509+
1510+ Description []
1511+
1512+ SideEffects []
1513+
1514+ SeeAlso []
1515+
1516+ ***********************************************************************/
1517+ void Gia_WriteMappedVerilog ( char * pFileName , Gia_Man_t * pGia , int fVerbose )
1518+ {
1519+ (void )fVerbose ;
1520+ if ( pFileName == NULL || pGia == NULL )
1521+ return ;
1522+ if ( !Gia_ManHasMapping (pGia ) )
1523+ {
1524+ printf ( "Cannot write LUT-based Verilog because AIG is not mapped.\n" );
1525+ return ;
1526+ }
1527+ GiaHie_DumpMappedLuts ( pGia , pFileName );
1528+ }
1529+
13171530////////////////////////////////////////////////////////////////////////
13181531/// END OF FILE ///
13191532////////////////////////////////////////////////////////////////////////
0 commit comments