diff --git a/abclib.dsp b/abclib.dsp index 2bcb6e1b8..500ffcaf0 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -3323,47 +3323,47 @@ SOURCE=.\src\opt\fxu\fxuUpdate.c # PROP Default_Filter "" # Begin Source File -SOURCE=.\src\opt\rar\rewire_map.h +SOURCE=.\src\opt\rar\rewireMap.h # End Source File # Begin Source File -SOURCE=.\src\opt\rar\rewire_miaig.h +SOURCE=.\src\opt\rar\rewireMiaig.h # End Source File # Begin Source File -SOURCE=.\src\opt\rar\rewire_rar.h +SOURCE=.\src\opt\rar\rewireRar.h # End Source File # Begin Source File -SOURCE=.\src\opt\rar\rewire_rng.h +SOURCE=.\src\opt\rar\rewireRng.h # End Source File # Begin Source File -SOURCE=.\src\opt\rar\rewire_time.h +SOURCE=.\src\opt\rar\rewireTime.h # End Source File # Begin Source File -SOURCE=.\src\opt\rar\rewire_tt.h +SOURCE=.\src\opt\rar\rewireTt.h # End Source File # Begin Source File -SOURCE=.\src\opt\rar\rewire_vec.h +SOURCE=.\src\opt\rar\rewireVec.h # End Source File # Begin Source File -SOURCE=.\src\opt\rar\rewire_map.c +SOURCE=.\src\opt\rar\rewireMap.c # End Source File # Begin Source File -SOURCE=.\src\opt\rar\rewire_miaig.cpp +SOURCE=.\src\opt\rar\rewireMiaig.cpp # End Source File # Begin Source File -SOURCE=.\src\opt\rar\rewire_rar.c +SOURCE=.\src\opt\rar\rewireRar.c # End Source File # Begin Source File -SOURCE=.\src\opt\rar\rewire_rng.c +SOURCE=.\src\opt\rar\rewireRng.c # End Source File # End Group # Begin Group "rwr" @@ -4991,6 +4991,10 @@ SOURCE=.\src\misc\util\utilPth.c # End Source File # Begin Source File +SOURCE=.\src\misc\util\utilPrefix.cpp +# End Source File +# Begin Source File + SOURCE=.\src\misc\util\utilSignal.c # End Source File # Begin Source File @@ -5755,6 +5759,10 @@ SOURCE=.\src\aig\gia\giaBound.c # End Source File # Begin Source File +SOURCE=.\src\aig\gia\giaBsFind.c +# End Source File +# Begin Source File + SOURCE=.\src\aig\gia\giaCCof.c # End Source File # Begin Source File diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index ee79ccd7a..1d0290c04 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1358,7 +1358,7 @@ extern Gia_Man_t * Gia_ManDupZero( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupPerm( Gia_Man_t * p, Vec_Int_t * vPiPerm ); extern Gia_Man_t * Gia_ManDupPermFlop( Gia_Man_t * p, Vec_Int_t * vFfPerm ); extern Gia_Man_t * Gia_ManDupPermFlopGap( Gia_Man_t * p, Vec_Int_t * vFfPerm ); -extern void Gia_ManDupAppend( Gia_Man_t * p, Gia_Man_t * pTwo ); +extern void Gia_ManDupAppend( Gia_Man_t * p, Gia_Man_t * pTwo, int fShareCis ); extern void Gia_ManDupAppendShare( Gia_Man_t * p, Gia_Man_t * pTwo ); extern Gia_Man_t * Gia_ManDupAppendNew( Gia_Man_t * pOne, Gia_Man_t * pTwo ); extern Gia_Man_t * Gia_ManDupAppendCones( Gia_Man_t * p, Gia_Man_t ** ppCones, int nCones, int fOnlyRegs ); diff --git a/src/aig/gia/giaBsFind.c b/src/aig/gia/giaBsFind.c new file mode 100644 index 000000000..61cb2c2cf --- /dev/null +++ b/src/aig/gia/giaBsFind.c @@ -0,0 +1,580 @@ +/**CFile**************************************************************** + + FileName [giaBsFind.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaBsFind.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "misc/util/utilTruth.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +// Cost function: sum of squared differences between all pairs +int cost_sum_squares(int* subset, int K, void * pData) { + double cost = 0; + for (int i = 0; i < K - 1; i++) { + for (int j = i + 1; j < K; j++) { + int diff = subset[i] - subset[j]; + cost += diff * diff; + } + } + // Normalize to be between 2 and 100 + return (int)(2.0 + (cost / (K * K)) * 0.98); +} + +// Compare function for qsort - for sorting individual subsets +int compare_ints(const void* a, const void* b) { + return *(int*)a - *(int*)b; +} + +// Compare function for qsort - for sorting subsets by cost +// Subset format: [K, element1, element2, ..., elementK, cost] +int compare_subsets_by_cost(const void* a, const void* b) { + const int* subset_a = (const int*)a; + const int* subset_b = (const int*)b; + int K_a = subset_a[0]; + int K_b = subset_b[0]; + assert( K_a == K_b ); + // Cost is at position K+1 (after K and K elements) + return subset_a[K_a + 1] - subset_b[K_b + 1]; +} + +// Generate a random subset of K numbers from 0 to N-1 +// Format: [K, element1, element2, ..., elementK, cost] +void generate_random_subset(int* subset, int K, int N) { + subset[0] = K; // Store K in first position + int count = 0; + + // First, generate K unique random numbers + while (count < K) { + int num = rand() % N; + + // Check if number already exists in subset + int exists = 0; + for (int i = 0; i < count; i++) { + if (subset[i + 1] == num) { + exists = 1; + break; + } + } + + if (!exists) { + subset[count + 1] = num; + count++; + } + } + + // Then, sort the subset using bubble sort + for (int i = 1; i < K; i++) { + for (int j = 1; j < K - i + 1; j++) { + if (subset[j] > subset[j + 1]) { + int temp = subset[j]; + subset[j] = subset[j + 1]; + subset[j + 1] = temp; + } + } + } +} + +// Create offspring from two parent subsets +// Uses pre-allocated arrays to avoid repeated memory allocation +void create_offspring(int* parent1, int* parent2, int* offspring, int K, int N, + int* in_offspring, int* in_parent1, int* in_parent2, int* candidates) { + int count = 0; + offspring[0] = K; // Store K in first position + + // Mark which numbers are in each parent (skip first element which is K) + for (int i = 1; i <= K; i++) { + in_parent1[parent1[i]] = 1; + in_parent2[parent2[i]] = 1; + } + + // First, add numbers that appear in both parents + for (int i = 0; i < N && count < K; i++) { + if (in_parent1[i] && in_parent2[i]) { + offspring[count + 1] = i; + count++; + in_offspring[i] = 1; + } + } + + // Create array of numbers that appear in exactly one parent + int num_candidates = 0; + + for (int i = 0; i < N; i++) { + if ((in_parent1[i] || in_parent2[i]) && !in_offspring[i]) { + candidates[num_candidates++] = i; + } + } + + // Randomly add from candidates until we have K numbers + while (count < K && num_candidates > 0) { + int idx = rand() % num_candidates; + offspring[count + 1] = candidates[idx]; + count++; + in_offspring[candidates[idx]] = 1; + + // Remove selected candidate + candidates[idx] = candidates[--num_candidates]; + } + + // Sort the offspring elements (not including the first K value) + qsort(&offspring[1], K, sizeof(int), compare_ints); + + // Clean up the intean arrays for next use - only clean used entries + for (int i = 1; i <= K; i++) { + in_parent1[parent1[i]] = 0; + in_parent2[parent2[i]] = 0; + } + for (int i = 1; i <= K; i++) { + in_offspring[offspring[i]] = 0; + } +} + +// Count unique subsets in a sorted array of subsets +// Returns the number of unique subsets and prints the percentage +int count_unique_subsets(int* sorted_subsets, int num_subsets, int subset_size, const char* label) { + if (num_subsets == 0) return 0; + + int unique_count = 1; // First subset is always unique + int K = sorted_subsets[0]; // Get K from first subset + + // Compare each subset with the previous one + for (int i = 1; i < num_subsets; i++) { + int* current = &sorted_subsets[i * subset_size]; + int* previous = &sorted_subsets[(i - 1) * subset_size]; + + // Compare all K elements (skip position 0 which has K, and K+1 which has cost) + int is_different = 0; + for (int j = 1; j <= K; j++) { + if (current[j] != previous[j]) { + is_different = 1; + break; + } + } + + if (is_different) { + unique_count++; + } + } + + double percentage = (unique_count * 100.0) / num_subsets; + printf("%s: %d unique subsets out of %d (%.1f%%)\n", + label, unique_count, num_subsets, percentage); + + return unique_count; +} + +// Main genetic algorithm +int genetic_subset_selection(int N, int K, int B, int L, + int verbose, + int (*cost_function)(int*, int, void *), + int** best_subsets_history, + int* iterations_used, + void * pUserData) { + int print_unique = 0; + int M = B * (B - 1) / 2; + int subset_size = K + 2; // K value + K elements + cost + + // Allocate arrays + int* current_generation = (int*)malloc(M * subset_size * sizeof(int)); + int* next_generation = (int*)malloc(M * subset_size * sizeof(int)); + int* all_best_subsets = (int*)calloc(B * L * subset_size, sizeof(int)); + + // Pre-allocate reusable arrays for create_offspring + int* in_offspring = (int*)calloc(N, sizeof(int)); + int* in_parent1 = (int*)calloc(N, sizeof(int)); + int* in_parent2 = (int*)calloc(N, sizeof(int)); + int* candidates = (int*)malloc(K * 2 * sizeof(int)); + + // Generate initial population + for (int i = 0; i < M; i++) { + int* subset = ¤t_generation[i * subset_size]; + generate_random_subset(subset, K, N); + // Cost function uses elements starting at position 1 + subset[K + 1] = cost_function(&subset[1], K, pUserData); + } + + // Sort to get best B subsets + qsort(current_generation, M, subset_size * sizeof(int), compare_subsets_by_cost); + if ( print_unique ) count_unique_subsets(current_generation, M, subset_size, "Initial population"); + + int best_cost = current_generation[K + 1]; + int generation = 0; + int total_best_count = 0; + + // Main evolutionary loop + while (generation < L) { + // Store best B subsets from current generation + for (int i = 0; i < B && total_best_count < B * L; i++) { + memcpy(&all_best_subsets[total_best_count * subset_size], + ¤t_generation[i * subset_size], + subset_size * sizeof(int)); + total_best_count++; + } + + if ( verbose ) { + printf( "Iter %d\n", generation ); + for (int i = 0; i < B; i++ ) { + printf( "Subset %2d : {", i ); + for (int k = 0; k < K; k++ ) + printf( " %2d", (¤t_generation[i * subset_size])[k+1] ); + printf( " } " ); + printf( "Cost %2d\n", (¤t_generation[i * subset_size])[K+1] ); + } + } + + // Create next generation from pairs of best B subsets + int offspring_idx = 0; + for (int i = 0; i < B; i++) { + for (int j = i + 1; j < B; j++) { + int* parent1 = ¤t_generation[i * subset_size]; + int* parent2 = ¤t_generation[j * subset_size]; + int* offspring = &next_generation[offspring_idx * subset_size]; + + create_offspring(parent1, parent2, offspring, K, N, + in_offspring, in_parent1, in_parent2, candidates); + offspring[K + 1] = cost_function(&offspring[1], K, pUserData); + offspring_idx++; + } + } + + // Sort next generation + qsort(next_generation, M, subset_size * sizeof(int), compare_subsets_by_cost); + if ( print_unique ) count_unique_subsets(next_generation, M, subset_size, "Next generation"); + + generation++; + + // Check for improvement + int new_best_cost = next_generation[K + 1]; + if (new_best_cost >= best_cost) { + break; // No improvement + } + + best_cost = new_best_cost; + + // Swap generations + int* temp = current_generation; + current_generation = next_generation; + next_generation = temp; + } + + // Sort all best subsets collected using qsort + qsort(all_best_subsets, total_best_count, subset_size * sizeof(int), compare_subsets_by_cost); + if ( print_unique ) count_unique_subsets(all_best_subsets, total_best_count, subset_size, "All best subsets"); + + if ( verbose ) { + printf( "Final best\n" ); + for (int i = 0; i < B; i++ ) { + printf( "Subset %2d : {", i ); + for (int k = 0; k < K; k++ ) + printf( " %2d", (&all_best_subsets[i * subset_size])[k+1] ); + printf( " } " ); + printf( "Cost %2d\n", (&all_best_subsets[i * subset_size])[K+1] ); + } + } + + // Free pre-allocated arrays + free(in_offspring); + free(in_parent1); + free(in_parent2); + free(candidates); + + // Return results + if (best_subsets_history != NULL) { + *best_subsets_history = all_best_subsets; + } else { + free(all_best_subsets); + } + + if (iterations_used != NULL) { + *iterations_used = generation + 1; + } + + free(current_generation); + free(next_generation); + + return best_cost; +} + +// Test bench +/* +int bs_find_test() { + srand(time(NULL)); + + // Test parameters + int N = 30; // Total numbers (0 to 29) + int K = 6; // Subset size + int B = 10; // Number of best subsets to keep + int L = 50; // Maximum iterations + + printf("Genetic Algorithm for Subset Selection\n"); + printf("======================================\n"); + printf("Parameters:\n"); + printf(" N (total numbers): %d\n", N); + printf(" K (subset size): %d\n", K); + printf(" B (best subsets): %d\n", B); + printf(" L (max iterations): %d\n", L); + printf("\n"); + + // Run the algorithm + int* best_subsets_history = NULL; + int iterations_used = 0; + int best_cost = genetic_subset_selection(N, K, B, L, 0, + cost_sum_squares, + &best_subsets_history, + &iterations_used); + + printf("Best cost found: %d\n", best_cost); + printf("Iterations until convergence: %d\n\n", iterations_used); + + // Display top 5 best subsets + printf("Top 5 best subsets:\n"); + int subset_size = K + 2; + for (int i = 0; i < 5 && i < B * L; i++) { + int* subset = &best_subsets_history[i * subset_size]; + if (subset[K + 1] == 0) break; // Check if cost is 0 (uninitialized) + + printf("Subset %d: {", i + 1); + for (int j = 1; j <= K; j++) { + printf("%d", subset[j]); + if (j < K) printf(", "); + } + printf("} - Cost: %d\n", subset[K + 1]); + } + + // Test with different parameters + printf("\n\nTesting with different parameters:\n"); + printf("==================================\n"); + + // Test 1: Smaller problem + N = 20; K = 4; B = 6; L = 30; + free(best_subsets_history); + best_subsets_history = NULL; + iterations_used = 0; + + best_cost = genetic_subset_selection(N, K, B, L, 0, + cost_sum_squares, + &best_subsets_history, + &iterations_used); + + printf("\nTest 1 - N=%d, K=%d, B=%d, L=%d\n", N, K, B, L); + printf("Best cost: %d\n", best_cost); + printf("Iterations until convergence: %d\n", iterations_used); + printf("Best subset: {"); + for (int j = 1; j <= K; j++) { + printf("%d", best_subsets_history[j]); + if (j < K) printf(", "); + } + printf("}\n"); + + // Test 2: Larger problem + N = 50; K = 8; B = 15; L = 100; + free(best_subsets_history); + best_subsets_history = NULL; + iterations_used = 0; + + best_cost = genetic_subset_selection(N, K, B, L, 0, + cost_sum_squares, + &best_subsets_history, + &iterations_used); + + printf("\nTest 2 - N=%d, K=%d, B=%d, L=%d\n", N, K, B, L); + printf("Best cost: %d\n", best_cost); + printf("Iterations until convergence: %d\n", iterations_used); + printf("Best subset: {"); + for (int j = 1; j <= K; j++) { + printf("%d", best_subsets_history[j]); + if (j < K) printf(", "); + } + printf("}\n"); + + // Test 3: Test convergence speed with different B values + printf("\n\nConvergence Speed Analysis:\n"); + printf("===========================\n"); + N = 40; K = 7; L = 100; + + for (int B_test = 5; B_test <= 20; B_test += 5) { + free(best_subsets_history); + best_subsets_history = NULL; + iterations_used = 0; + + best_cost = genetic_subset_selection(N, K, B_test, L, 0, + cost_sum_squares, + &best_subsets_history, + &iterations_used); + + printf("B=%2d: Best cost=%3d, Iterations=%3d\n", + B_test, best_cost, iterations_used); + } + + free(best_subsets_history); + + return 0; +} +*/ + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wrd_t * Gia_ManBsFindStart( Gia_Man_t * pGia, int nWords ) +{ + Vec_Wrd_t * vSims = Vec_WrdStartRandom( (Gia_ManCiNum(pGia) + 1) * nWords ); + Vec_WrdFillExtra( vSims, Gia_ManObjNum(pGia) * nWords, 0 ); + Abc_TtClear( Vec_WrdArray(vSims), nWords ); + return vSims; +} +void Gia_ManBsFindNext( Gia_Man_t * pGia, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsOuts, int iMint ) +{ + Gia_Obj_t * pObj; int i; + word * pSims[2], * pSim; + Gia_ManForEachAnd( pGia, pObj, i ) { + pSim = Vec_WrdEntryP( vSims, i * nWords ); + pSims[0] = Vec_WrdEntryP( vSims, Gia_ObjFaninId0(pObj, i) * nWords ); + pSims[1] = Vec_WrdEntryP( vSims, Gia_ObjFaninId1(pObj, i) * nWords ); + Abc_TtAndCompl( pSim, pSims[0], Gia_ObjFaninC0(pObj), pSims[1], Gia_ObjFaninC1(pObj), nWords ); + } + Gia_ManForEachCo( pGia, pObj, i ) { + pSim = Vec_WrdEntryP( vSimsOuts, (iMint * Gia_ManCoNum(pGia) + i) * nWords ); + pSims[0] = Vec_WrdEntryP( vSims, Gia_ObjFaninId0p(pGia, pObj) * nWords ); + Abc_TtCopy( pSim, pSims[0], nWords, Gia_ObjFaninC0(pObj) ); + } +} +int Gia_ManBsFindMyu( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsOuts, Vec_Int_t * vVarNums, Vec_Wrd_t * vTemp ) +{ + int nMints = 1 << Vec_IntSize(vVarNums); + int nWordsAll = Gia_ManCoNum(p) * nWords; + int nMyu = 0, pMyu[256], i, k, Var; + assert( nMints <= 256 ); + assert( Vec_WrdSize(vTemp) == nWords * Vec_IntSize(vVarNums) ); + assert( Vec_WrdSize(vSimsOuts) == nMints * nWordsAll ); + Vec_IntForEachEntry( vVarNums, Var, i ) + Abc_TtCopy( Vec_WrdEntryP(vTemp, i * nWords), Vec_WrdEntryP(vSims, Gia_ManCiIdToId(p, Var) * nWords), nWords, 0 ); + for ( int m = 0; m < nMints; m++ ) { + Vec_IntForEachEntry( vVarNums, Var, i ) + Abc_TtConst( Vec_WrdEntryP(vSims, Gia_ManCiIdToId(p, Var) * nWords), nWords, (m >> i) & 1 ); + Gia_ManBsFindNext( p, nWords, vSims, vSimsOuts, m ); + } + Vec_IntForEachEntry( vVarNums, Var, i ) + Abc_TtCopy( Vec_WrdEntryP(vSims, Gia_ManCiIdToId(p, Var) * nWords), Vec_WrdEntryP(vTemp, i * nWords), nWords, 0 ); + for ( i = 0; i < nMints; i++ ) { + word * pSim = Vec_WrdEntryP(vSimsOuts, nWordsAll * i); + for ( k = 0; k < nMyu; k++ ) + if ( Abc_TtEqual(pSim, Vec_WrdEntryP(vSimsOuts, nWordsAll * pMyu[k]), nWordsAll) ) + break; + if ( k == nMyu ) + pMyu[nMyu++] = i; + } + return nMyu; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +typedef struct BsFind_UserData_t_ { + Gia_Man_t * pGia; + int nWords; + Vec_Wrd_t * vSims; + Vec_Wrd_t * vSimsOuts; + Vec_Int_t * vVarNums; + Vec_Wrd_t * vTemp; +} BsFind_UserData_t; + +BsFind_UserData_t * Gia_ManBsFindMyuFunctionStart( Gia_Man_t * pGia, int nWords, int nLutSize ) +{ + BsFind_UserData_t * p = ABC_CALLOC( BsFind_UserData_t, 1 ); + p->pGia = pGia; + p->nWords = nWords; + p->vSims = Gia_ManBsFindStart( pGia, nWords ); + p->vSimsOuts = Vec_WrdStart( (1 << nLutSize) * Gia_ManCoNum(pGia) * nWords ); + p->vVarNums = Vec_IntAlloc( nLutSize ); + p->vTemp = Vec_WrdStart( nLutSize * nWords ); + return p; +} +int Gia_ManBsFindMyuFunction( int * subset, int K, void * pUserData ) +{ + BsFind_UserData_t * p = (BsFind_UserData_t *)pUserData; + Vec_IntClear( p->vVarNums ); + for ( int i = 0; i < K; i++ ) + Vec_IntPush( p->vVarNums, subset[i] ); + return Gia_ManBsFindMyu( p->pGia, p->nWords, p->vSims, p->vSimsOuts, p->vVarNums, p->vTemp ); +} +void Gia_ManBsFindMyuFunctionStop( BsFind_UserData_t * p ) +{ + Vec_WrdFree( p->vSims ); + Vec_WrdFree( p->vSimsOuts ); + Vec_WrdFree( p->vTemp ); + Vec_IntFree( p->vVarNums ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManBsFindBest( Gia_Man_t * pGia, int nWords, int nLutSize, int nBest, int nIterMax, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Abc_Random(1); + BsFind_UserData_t * p = Gia_ManBsFindMyuFunctionStart( pGia, nWords, nLutSize ); + int nIters = 0, Res = genetic_subset_selection( Gia_ManCiNum(pGia), nLutSize, nBest, nIterMax, fVerbose, Gia_ManBsFindMyuFunction, NULL, &nIters, (void *)p ); + printf( "The best Myu %d was found after considering %d bound-sets in %d iterations. ", Res, nIters*nBest*(nBest-1)/2, nIters ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Gia_ManBsFindMyuFunctionStop( p ); + return Res; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index cca6f3d4c..8eb3e928f 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -1134,7 +1134,7 @@ Gia_Man_t * Gia_ManDupRandPerm( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -void Gia_ManDupAppend( Gia_Man_t * pNew, Gia_Man_t * pTwo ) +void Gia_ManDupAppend( Gia_Man_t * pNew, Gia_Man_t * pTwo, int fShareCis ) { Gia_Obj_t * pObj; int i; @@ -1148,7 +1148,7 @@ void Gia_ManDupAppend( Gia_Man_t * pNew, Gia_Man_t * pTwo ) if ( Gia_ObjIsAnd(pObj) ) pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); else if ( Gia_ObjIsCi(pObj) ) - pObj->Value = Gia_ManAppendCi( pNew ); + pObj->Value = fShareCis ? Gia_ManCiLit(pNew, Gia_ObjCioId(pObj)) : Gia_ManAppendCi( pNew ); else if ( Gia_ObjIsCo(pObj) ) pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); } @@ -6041,7 +6041,7 @@ Vec_Wec_t * Gia_ManCollectIntTfos( Gia_Man_t * p, Vec_Int_t * vVarNums ) Gia_Man_t * Gia_ManDupCofs( Gia_Man_t * p, Vec_Int_t * vVarNums ) { int i, iLit, nMints = 1 << Vec_IntSize(vVarNums); - Vec_Int_t * vOutLits = Vec_IntAlloc( nMints * Gia_ManCoNum(p) ); + Vec_Int_t * vOutLits = Vec_IntStartFull( nMints * Gia_ManCoNum(p) ); Vec_Wec_t * vTfos = Gia_ManCollectIntTfos( p, vVarNums ); Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; assert( Gia_ManRegNum(p) == 0 ); @@ -6057,7 +6057,7 @@ Gia_Man_t * Gia_ManDupCofs( Gia_Man_t * p, Vec_Int_t * vVarNums ) Gia_ManForEachAnd( p, pObj, i ) pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( p, pObj, i ) - Vec_IntPush( vOutLits, Gia_ObjFanin0Copy(pObj) ); + Vec_IntWriteEntry( vOutLits, i, Gia_ObjFanin0Copy(pObj) ); int m, g, x, b = 0; for ( m = 1; m < nMints; m++ ) { @@ -6067,7 +6067,7 @@ Gia_Man_t * Gia_ManDupCofs( Gia_Man_t * p, Vec_Int_t * vVarNums ) Gia_ManForEachObjVec( vNode, p, pObj, i ) pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( p, pObj, i ) - Vec_IntPush( vOutLits, Gia_ObjFanin0Copy(pObj) ); + Vec_IntWriteEntry( vOutLits, g * Gia_ManCoNum(p) + i, Gia_ObjFanin0Copy(pObj) ); } assert( Vec_IntFindMin(vOutLits) >= 0 ); Vec_IntForEachEntry( vOutLits, iLit, i ) @@ -6272,6 +6272,40 @@ Gia_Man_t * Gia_ManDupFanouts( Gia_Man_t * p ) return pNew; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDupChoicesMarkTfi_rec( Gia_Man_t * pGia, int iObj ) +{ + if ( Gia_ObjIsTravIdCurrentId(pGia, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(pGia, iObj); + Gia_Obj_t * pObj = Gia_ManObj(pGia, iObj); + if ( !Gia_ObjIsAnd(pObj) ) + return; + Gia_ManDupChoicesMarkTfi_rec( pGia, Gia_ObjFaninId0(pObj, iObj) ); + Gia_ManDupChoicesMarkTfi_rec( pGia, Gia_ObjFaninId1(pObj, iObj) ); + Gia_Obj_t * pSibl = Gia_ObjSiblObj( pGia, iObj ); + if ( pSibl ) Gia_ManDupChoicesMarkTfi_rec( pGia, Gia_ObjId(pGia, pSibl) ); +} +int Gia_ManDupChoicesCheckOverlap( Gia_Man_t * pGia, int iObj, int iFan0, int iFan1 ) +{ + Gia_ManIncrementTravId( pGia ); + Gia_ManDupChoicesMarkTfi_rec( pGia, Gia_ObjFaninId0(Gia_ManObj(pGia, iObj), iObj) ); + Gia_ManDupChoicesMarkTfi_rec( pGia, Gia_ObjFaninId1(Gia_ManObj(pGia, iObj), iObj) ); + if ( Gia_ObjIsTravIdCurrentId(pGia, iFan0) || Gia_ObjIsTravIdCurrentId(pGia, iFan1) ) + return 1; + return 0; +} + /**Function************************************************************* Synopsis [Reorders choice nodes.] @@ -6288,14 +6322,24 @@ void Gia_ManPrintChoices( Gia_Man_t * p ) Gia_Obj_t * pObj; int i; Gia_ManForEachAnd( p, pObj, i ) if ( p->pSibls[i] ) - printf( "%d -> %d\n", i, p->pSibls[i] ); + printf( "%d -> %d ", i, p->pSibls[i] ); } void Gia_ManReorderChoices_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( ~pObj->Value ) return; assert( Gia_ObjIsAnd(pObj) ); - Gia_Obj_t * pSibl = Gia_ObjSiblObj(p, Gia_ObjId(p, pObj)); + int ObjId = Gia_ObjId(p, pObj); + Gia_Obj_t * pSibl = Gia_ObjSiblObj(p, ObjId); + if ( pSibl ) { + int SiblId = Gia_ObjId(p, pSibl); + if ( Gia_ManDupChoicesCheckOverlap( p, SiblId, Gia_ObjFaninId0(pObj, ObjId), Gia_ObjFaninId1(pObj, ObjId) ) ) { + assert( p->pSibls[ObjId] == SiblId ); + p->pSibls[ObjId] = p->pSibls[SiblId]; + Gia_ManReorderChoices_rec( pNew, p, pObj ); + return; + } + } Gia_ManReorderChoices_rec( pNew, p, Gia_ObjFanin0(pObj) ); Gia_ManReorderChoices_rec( pNew, p, Gia_ObjFanin1(pObj) ); if ( pSibl ) Gia_ManReorderChoices_rec( pNew, p, pSibl ); diff --git a/src/aig/gia/giaGen.c b/src/aig/gia/giaGen.c index 088b64191..c22cb21f8 100644 --- a/src/aig/gia/giaGen.c +++ b/src/aig/gia/giaGen.c @@ -1192,9 +1192,9 @@ Gia_Man_t * Gia_ManGenNeuron( char * pFileName, int nIBits, int nLutSize, int fD SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManDupGenComp( int nBits, int fInterleave ) +Gia_Man_t * Gia_ManDupGenComp( int nBits, int fInterleave, int fSigned ) { - Gia_Man_t * pNew, * pTemp; int i, iLit = 1; + Gia_Man_t * pNew, * pTemp; int i, iLit = 1, iLitXor = 0, iLitB = 0; Vec_Int_t * vBitsA = Vec_IntAlloc( nBits + 1 ); Vec_Int_t * vBitsB = Vec_IntAlloc( nBits + 1 ); pNew = Gia_ManStart( 6*nBits+10 ); @@ -1211,6 +1211,10 @@ Gia_Man_t * Gia_ManDupGenComp( int nBits, int fInterleave ) for ( i = 0; i < nBits; i++ ) Vec_IntPush( vBitsB, Gia_ManAppendCi(pNew) ); } + if ( fSigned ) { + iLitXor = Gia_ManHashXor( pNew, Vec_IntPop(vBitsA), (iLitB = Vec_IntPop(vBitsB)) ); + nBits--; + } Vec_IntPush( vBitsA, 0 ); Vec_IntPush( vBitsB, 0 ); for ( i = 0; i < nBits; i++ ) { @@ -1227,7 +1231,10 @@ Gia_Man_t * Gia_ManDupGenComp( int nBits, int fInterleave ) int iOrLit = Gia_ManHashOr(pNew, iOrLit0, iOrLit1 ); iLit = Gia_ManHashOr(pNew, Abc_LitNot(iLit), iOrLit ); } - Gia_ManAppendCo( pNew, Abc_LitNotCond(iLit, nBits&1) ); + iLit = Abc_LitNotCond(iLit, nBits&1); + if ( fSigned ) + iLit = Gia_ManHashMux(pNew, iLitXor, iLitB, iLit ); + Gia_ManAppendCo( pNew, iLit ); pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); Vec_IntFree( vBitsA ); diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index 2f271e35c..efedcfb0a 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -2373,6 +2373,38 @@ Gia_Man_t * Gia_GenPutOnTop( char ** pFNames, int nFNames ) return pNew; } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManDupFromArray( int * pObjs, int nObjs, int nIns, int nLatches, int nOuts, int nAnds ) +{ + Gia_Man_t * pNew = Gia_ManStart( nObjs ); int i; + for ( i = 0; i < nIns + nLatches; i++ ) + Gia_ManAppendCi(pNew); + for ( i = 0; i < nAnds; i++ ) + { + int uLit = 2*(1+nIns+nLatches+i); + int uLit0 = pObjs[uLit+0]; + int uLit1 = pObjs[uLit+1]; + int uLit2 = Gia_ManAppendAnd( pNew, uLit0, uLit1 ); + assert( uLit2 == uLit ); + } + for ( i = 0; i < nOuts + nLatches; i++ ) + Gia_ManAppendCo( pNew, pObjs[2*(nObjs-nOuts-nLatches+i)+0] ); + Gia_ManSetRegNum(pNew, nLatches); + return pNew; +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaStoch.c b/src/aig/gia/giaStoch.c index c88bdae6b..53e491171 100644 --- a/src/aig/gia/giaStoch.c +++ b/src/aig/gia/giaStoch.c @@ -296,7 +296,7 @@ void Gia_ManStochSynthesis( Vec_Ptr_t * vAigs, char * pScript ) SeeAlso [] ***********************************************************************/ -int Gia_ManFilterPartitions( Gia_Man_t * p, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvNodes, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vWins, Vec_Int_t * vGains ) +int Gia_ManFilterPartitions( Gia_Man_t * p, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvNodes, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vWins, Vec_Int_t * vGains, int fDelayOpt ) { int RetValue = Vec_PtrSize(vvIns); Vec_Ptr_t * vvInsNew = Vec_PtrAlloc( 10 ); @@ -312,8 +312,8 @@ int Gia_ManFilterPartitions( Gia_Man_t * p, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvNod Vec_PtrPush( vvInsNew, Vec_IntDup((Vec_Int_t *)Vec_PtrEntry(vvIns, iEntry)) ); Vec_PtrPush( vvOutsNew, Vec_IntDup((Vec_Int_t *)Vec_PtrEntry(vvOuts, iEntry)) ); Vec_PtrPush( vvWinsNew, Gia_ManDupDfs((Gia_Man_t *)Vec_PtrEntry(vWins, iEntry)) ); - extern void Gia_ManMarkTfiTfo( Vec_Int_t * vOne, Gia_Man_t * pMan ); - Gia_ManMarkTfiTfo( (Vec_Int_t *)Vec_PtrEntryLast(vvInsNew), p ); + extern void Gia_ManMarkTfiTfo( Vec_Int_t * vOne, Gia_Man_t * pMan, int fDelayOpt ); + Gia_ManMarkTfiTfo( (Vec_Int_t *)Vec_PtrEntryLast(vvInsNew), p, fDelayOpt ); Vec_IntForEachEntry( vGains, Gain, i ) { if ( Gain < 0 ) continue; @@ -556,12 +556,14 @@ void Gia_ManSelectRemove( Vec_Wec_t * vSupps, Vec_Int_t * vOne ) Vec_WecRemoveEmpty( vSupps ); } // marks TFI/TFO of this one -void Gia_ManMarkTfiTfo( Vec_Int_t * vOne, Gia_Man_t * pMan ) +void Gia_ManMarkTfiTfo( Vec_Int_t * vOne, Gia_Man_t * pMan, int fDelayOpt ) { int i; Gia_Obj_t * pObj; Gia_ManForEachObjVec( vOne, pMan, pObj, i ) { - //Gia_ObjSetTravIdPrevious(pMan, pObj); - //Gia_ObjDfsMark_rec( pMan, pObj ); + if ( fDelayOpt ) { + Gia_ObjSetTravIdPrevious(pMan, pObj); + Gia_ObjDfsMark_rec( pMan, pObj ); + } Gia_ObjSetTravIdPrevious(pMan, pObj); Gia_ObjDfsMark2_rec( pMan, pObj ); } @@ -632,7 +634,7 @@ Vec_Ptr_t * Gia_ManDeriveWinInsAll( Vec_Wec_t * vSupps, int nSuppMax, Gia_Man_t } return vRes; } -Gia_Man_t * Gia_ManDupFromArrays( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos ) +Gia_Man_t * Gia_ManDupFromArrays( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, Vec_Int_t * vLevels[2], int nLevels ) { Gia_Man_t * pNew; Gia_Obj_t * pObj; @@ -647,23 +649,20 @@ Gia_Man_t * Gia_ManDupFromArrays( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * v pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachObjVec( vCos, p, pObj, i ) pObj->Value = Gia_ManAppendCo( pNew, pObj->Value ); - return pNew; -} -Vec_Ptr_t * Gia_ManDupWindows( Gia_Man_t * pMan, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvNodes, Vec_Ptr_t * vvOuts ) -{ - Vec_Int_t * vNodes; int i; - Vec_Ptr_t * vWins = Vec_PtrAlloc( Vec_PtrSize(vvIns) ); - assert( Vec_PtrSize(vvIns) == Vec_PtrSize(vvNodes) ); - assert( Vec_PtrSize(vvOuts) == Vec_PtrSize(vvNodes) ); - Gia_ManFillValue( pMan ); - Gia_ManCleanMark01( pMan ); - Vec_PtrForEachEntry( Vec_Int_t *, vvNodes, vNodes, i ) { - Vec_Int_t * vIns = (Vec_Int_t *)Vec_PtrEntry(vvIns, i); - Vec_Int_t * vOuts = (Vec_Int_t *)Vec_PtrEntry(vvOuts, i); - Gia_Man_t * pNew = Gia_ManDupFromArrays( pMan, vIns, vNodes, vOuts ); - Vec_PtrPush( vWins, pNew ); + if ( vLevels[0] && vLevels[1] ) { + pNew->vCiArrs = Vec_IntAlloc( Gia_ManCiNum(pNew) ); + Gia_ManForEachObjVec( vCis, p, pObj, i ) { + // Vec_IntPush( pNew->vCiArrs, Gia_ObjLevel(p, pObj) ); + Vec_IntPush( pNew->vCiArrs, Vec_IntEntry(vLevels[0], Gia_ObjId(p, pObj)) ); + } + pNew->vCoReqs = Vec_IntAlloc( Gia_ManCoNum(pNew) ); + Gia_ManForEachObjVec( vCos, p, pObj, i ) { + // Vec_IntPush( pNew->vCoReqs, nLevels - Gia_ObjLevel(p, pObj) ); + Vec_IntPush( pNew->vCoReqs, nLevels + 1 - Vec_IntEntry(vLevels[1], Gia_ObjId(p, pObj)) ); + assert( Gia_ObjIsAnd(pObj) ); + } } - return vWins; + return pNew; } int Gia_ManLevelR( Gia_Man_t * pMan ) { @@ -675,7 +674,35 @@ int Gia_ManLevelR( Gia_Man_t * pMan ) Gia_ObjSetLevel( pMan, pNode, 0 ); return LevelMax; } -Vec_Ptr_t * Gia_ManExtractPartitions( Gia_Man_t * pMan, int Iter, int nSuppMax, Vec_Ptr_t ** pvIns, Vec_Ptr_t ** pvOuts, Vec_Ptr_t ** pvNodes, int fOverlap ) +Vec_Ptr_t * Gia_ManDupWindows( Gia_Man_t * pMan, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvNodes, Vec_Ptr_t * vvOuts, int fDelayOpt ) +{ + // compute direct and reverse level + Vec_Int_t * vLevels[2] = {NULL}; + if ( fDelayOpt ) { + int Levels[2]; + Levels[0] = Gia_ManLevelNum( pMan ); + ABC_SWAP( Vec_Int_t *, vLevels[0], pMan->vLevels ); + Levels[1] = Gia_ManLevelRNum( pMan ); + ABC_SWAP( Vec_Int_t *, vLevels[1], pMan->vLevels ); + assert( (Levels[0] + 1) == Levels[1] ); + } + Vec_Int_t * vNodes; int i; + Vec_Ptr_t * vWins = Vec_PtrAlloc( Vec_PtrSize(vvIns) ); + assert( Vec_PtrSize(vvIns) == Vec_PtrSize(vvNodes) ); + assert( Vec_PtrSize(vvOuts) == Vec_PtrSize(vvNodes) ); + Gia_ManFillValue( pMan ); + Gia_ManCleanMark01( pMan ); + Vec_PtrForEachEntry( Vec_Int_t *, vvNodes, vNodes, i ) { + Vec_Int_t * vIns = (Vec_Int_t *)Vec_PtrEntry(vvIns, i); + Vec_Int_t * vOuts = (Vec_Int_t *)Vec_PtrEntry(vvOuts, i); + Gia_Man_t * pNew = Gia_ManDupFromArrays( pMan, vIns, vNodes, vOuts, vLevels, pMan->nLevels ); + Vec_PtrPush( vWins, pNew ); + } + Vec_IntFreeP( &vLevels[0] ); + Vec_IntFreeP( &vLevels[1] ); + return vWins; +} +Vec_Ptr_t * Gia_ManExtractPartitions( Gia_Man_t * pMan, int Iter, int nSuppMax, Vec_Ptr_t ** pvIns, Vec_Ptr_t ** pvOuts, Vec_Ptr_t ** pvNodes, int fOverlap, int fDelayOpt ) { // if ( Gia_ManCiNum(pMan) <= nSuppMax ) { // Vec_Ptr_t * vWins = Vec_PtrAlloc( 1 ); @@ -695,7 +722,7 @@ Vec_Ptr_t * Gia_ManExtractPartitions( Gia_Man_t * pMan, int Iter, int nSuppMax, Vec_Ptr_t * vIns = Gia_ManDeriveWinInsAll( vSupps, nSuppMax, pMan, fOverlap ); Vec_Ptr_t * vNodes = Gia_ManDeriveWinNodesAll( pMan, vIns, vStore ); Vec_Ptr_t * vOuts = Gia_ManDeriveWinOutsAll( pMan, vNodes ); - Vec_Ptr_t * vWins = Gia_ManDupWindows( pMan, vIns, vNodes, vOuts ); + Vec_Ptr_t * vWins = Gia_ManDupWindows( pMan, vIns, vNodes, vOuts, fDelayOpt ); Vec_WecFree( vSupps ); Vec_WecFree( vStore ); *pvIns = vIns; @@ -742,7 +769,7 @@ void Gia_ManCollectNodes( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Ve Vec_IntForEachEntry( vCos, iObj, i ) Gia_ManCollectNodes_rec( p, iObj, vAnds ); } -Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos ) +Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, Vec_Int_t * vLevels[2], int nLevels ) { Vec_Int_t * vMapping; int i; Gia_Man_t * pNew; Gia_Obj_t * pObj; @@ -757,8 +784,16 @@ Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vA Gia_ManForEachObjVec( vCos, p, pObj, i ) Gia_ManAppendCo( pNew, pObj->Value ); assert( Gia_ManCiNum(pNew) > 0 && Gia_ManCoNum(pNew) > 0 ); - if ( !Gia_ManHasMapping(p) ) + if ( !Gia_ManHasMapping(p) ) { + if ( vLevels[0] == NULL ) return pNew; + pNew->vCiArrs = Vec_IntAlloc( Gia_ManCiNum(pNew) ); + Gia_ManForEachObjVec( vCis, p, pObj, i ) + Vec_IntPush( pNew->vCiArrs, Gia_ObjLevel(p, pObj) ); + pNew->vCoReqs = Vec_IntAlloc( Gia_ManCoNum(pNew) ); + Gia_ManForEachObjVec( vCos, p, pObj, i ) + Vec_IntPush( pNew->vCoReqs, nLevels - Gia_ObjLevel(p, pObj) ); return pNew; + } vMapping = Vec_IntAlloc( 4*Gia_ManObjNum(pNew) ); Vec_IntFill( vMapping, Gia_ManObjNum(pNew), 0 ); Gia_ManForEachObjVec( vAnds, p, pObj, i ) @@ -776,17 +811,29 @@ Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vA pNew->vMapping = vMapping; return pNew; } -Vec_Ptr_t * Gia_ManDupDivide( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, char * pScript, int nProcs, int TimeOut ) +Vec_Ptr_t * Gia_ManDupDivide( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, char * pScript, int nProcs, int TimeOut, int fDelayOpt ) { + // compute direct and reverse level + Vec_Int_t * vLevels[2] = {NULL}; + if ( fDelayOpt ) { + int Levels[2]; + Levels[0] = Gia_ManLevelNum( p ); + ABC_SWAP( Vec_Int_t *, vLevels[0], p->vLevels ); + Levels[1] = Gia_ManLevelRNum( p ); + ABC_SWAP( Vec_Int_t *, vLevels[1], p->vLevels ); + // assert( Levels[0] == Levels[1] ); + } Vec_Ptr_t * vAigs = Vec_PtrAlloc( Vec_WecSize(vCis) ); int i; for ( i = 0; i < Vec_WecSize(vCis); i++ ) { Gia_ManCollectNodes( p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i) ); - Vec_PtrPush( vAigs, Gia_ManDupDivideOne(p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i)) ); + Vec_PtrPush( vAigs, Gia_ManDupDivideOne(p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i), vLevels, p->nLevels) ); } //Gia_ManStochSynthesis( vAigs, pScript ); Vec_Int_t * vGains = Gia_StochProcess( vAigs, pScript, nProcs, TimeOut, 0 ); Vec_IntFree( vGains ); + Vec_IntFreeP( &vLevels[0] ); + Vec_IntFreeP( &vLevels[1] ); return vAigs; } Gia_Man_t * Gia_ManDupStitch( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, Vec_Ptr_t * vAigs, int fHash ) @@ -982,7 +1029,7 @@ Vec_Wec_t * Gia_ManStochOutputs( Gia_Man_t * p, Vec_Wec_t * vAnds ) SeeAlso [] ***********************************************************************/ -void Gia_ManStochSyn( int nSuppMax, int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript, int nProcs ) +void Gia_ManStochSyn( int nSuppMax, int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript, int nProcs, int fDelayOpt ) { abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0; abctime clkStart = Abc_Clock(); @@ -1008,7 +1055,7 @@ void Gia_ManStochSyn( int nSuppMax, int nMaxSize, int nIters, int TimeOut, int S Vec_Wec_t * vAnds = Gia_ManStochNodes( pGia, nMaxSize, Abc_Random(0) & 0x7FFFFFFF ); Vec_Wec_t * vIns = Gia_ManStochInputs( pGia, vAnds ); Vec_Wec_t * vOuts = Gia_ManStochOutputs( pGia, vAnds ); - Vec_Ptr_t * vAigs = Gia_ManDupDivide( pGia, vIns, vAnds, vOuts, pScript, nProcs, TimeOut ); + Vec_Ptr_t * vAigs = Gia_ManDupDivide( pGia, vIns, vAnds, vOuts, pScript, nProcs, TimeOut, fDelayOpt ); Gia_Man_t * pNew = Gia_ManDupStitchMap( pGia, vIns, vAnds, vOuts, vAigs ); int fMapped = Gia_ManHasMapping(pGia) && Gia_ManHasMapping(pNew); Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pNew ); @@ -1039,9 +1086,9 @@ void Gia_ManStochSyn( int nSuppMax, int nMaxSize, int nIters, int TimeOut, int S extern Gia_Man_t * Gia_ManDupInsertWindows( Gia_Man_t * p, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vAigs ); abctime clk = Abc_Clock(); Gia_Man_t * pGia = Gia_ManDup( Abc_FrameReadGia(Abc_FrameGetGlobalFrame()) ); Gia_ManStaticFanoutStart(pGia); - Vec_Ptr_t * vAigs = Gia_ManExtractPartitions( pGia, i, nSuppMax, &vIns, &vOuts, &vNodes, fOverlap ); + Vec_Ptr_t * vAigs = Gia_ManExtractPartitions( pGia, i, nSuppMax, &vIns, &vOuts, &vNodes, fOverlap, fDelayOpt ); Vec_Int_t * vGains = Gia_StochProcess( vAigs, pScript, nProcs, TimeOut, 0 ); - int nPartsInit = fOverlap ? Gia_ManFilterPartitions( pGia, vIns, vNodes, vOuts, vAigs, vGains ) : Vec_PtrSize(vIns); + int nPartsInit = fOverlap ? Gia_ManFilterPartitions( pGia, vIns, vNodes, vOuts, vAigs, vGains, fDelayOpt ) : Vec_PtrSize(vIns); Gia_Man_t * pNew = Gia_ManDupInsertWindows( pGia, vIns, vOuts, vAigs ); Gia_ManStaticFanoutStop(pGia); Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pNew ); if ( fVerbose ) diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 2e64d1d1b..b4e2efb8b 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -6,6 +6,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaBalLut.c \ src/aig/gia/giaBalMap.c \ src/aig/gia/giaBidec.c \ + src/aig/gia/giaBsFind.c \ src/aig/gia/giaCCof.c \ src/aig/gia/giaCex.c \ src/aig/gia/giaClp.c \ diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index c9150ea8c..fe655d1ed 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -636,11 +636,13 @@ static int Abc_CommandAbc9GenComp ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9GenSorter ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9GenNeuron ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9GenAdder ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9GenPrefix ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Window ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9FunAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9DsdInfo ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9FunTrace ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9MulFind ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9BsFind ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9AndCare ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Test ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1460,12 +1462,14 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&gensorter", Abc_CommandAbc9GenSorter, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&genneuron", Abc_CommandAbc9GenNeuron, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&genadder", Abc_CommandAbc9GenAdder, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&genprefix", Abc_CommandAbc9GenPrefix, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&window", Abc_CommandAbc9Window, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&funabs", Abc_CommandAbc9FunAbs, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&dsdinfo", Abc_CommandAbc9DsdInfo, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&funtrace", Abc_CommandAbc9FunTrace, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&mulfind", Abc_CommandAbc9MulFind, 0 ); - Cmd_CommandAdd( pAbc, "ABC9", "&andcare", Abc_CommandAbc9AndCare, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&bsfind", Abc_CommandAbc9BsFind, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&andcare", Abc_CommandAbc9AndCare, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&test", Abc_CommandAbc9Test, 0 ); @@ -8615,7 +8619,9 @@ int Abc_CommandResubstitute( Abc_Frame_t * pAbc, int argc, char ** argv ) int fUseZeros; int fVerbose; int fVeryVerbose; - extern int Abc_NtkResubstitute( Abc_Ntk_t * pNtk, int nCutsMax, int nNodesMax, int nMinSaved, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose ); + int Log2Probs; + int Log2Divs; + extern int Abc_NtkResubstitute( Abc_Ntk_t * pNtk, int nCutsMax, int nNodesMax, int nMinSaved, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int Log2Probs, int Log2Divs ); // set defaults nCutsMax = 8; @@ -8626,8 +8632,10 @@ int Abc_CommandResubstitute( Abc_Frame_t * pAbc, int argc, char ** argv ) fUseZeros = 0; fVerbose = 0; fVeryVerbose = 0; + Log2Probs = 0; + Log2Divs = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KNMFlzvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KNMFlzvwhPDV" ) ) != EOF ) { switch ( c ) { @@ -8675,6 +8683,41 @@ int Abc_CommandResubstitute( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nLevelsOdc < 0 ) goto usage; break; + + case 'P': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); + goto usage; + } + Log2Probs = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( Log2Probs < 0 ) + goto usage; + break; + case 'D': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-D\" should be followed by an integer.\n" ); + goto usage; + } + Log2Divs = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( Log2Divs < 0 ) + goto usage; + break; + case 'V': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-V\" should be followed by an integer.\n" ); + goto usage; + } + nCutsMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nCutsMax < 0 ) + goto usage; + break; + case 'l': fUpdateLevel ^= 1; break; @@ -8725,7 +8768,7 @@ int Abc_CommandResubstitute( Abc_Frame_t * pAbc, int argc, char ** argv ) } // modify the current network - if ( !Abc_NtkResubstitute( pNtk, nCutsMax, nNodesMax, nMinSaved, nLevelsOdc, fUpdateLevel, fVerbose, fVeryVerbose ) ) + if ( !Abc_NtkResubstitute( pNtk, nCutsMax, nNodesMax, nMinSaved, nLevelsOdc, fUpdateLevel, fVerbose, fVeryVerbose, Log2Probs, Log2Divs ) ) { Abc_Print( -1, "Refactoring has failed.\n" ); return 1; @@ -8733,7 +8776,7 @@ int Abc_CommandResubstitute( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: resub [-KNMF ] [-lzvwh]\n" ); + Abc_Print( -2, "usage: resub [-KNMF ] [-lzvwh] [-PDV ]\n" ); Abc_Print( -2, "\t performs technology-independent restructuring of the AIG\n" ); Abc_Print( -2, "\t-K : the max cut size (%d <= num <= %d) [default = %d]\n", RS_CUT_MIN, RS_CUT_MAX, nCutsMax ); Abc_Print( -2, "\t-N : the max number of nodes to add (0 <= num <= 3) [default = %d]\n", nNodesMax ); @@ -8743,7 +8786,16 @@ usage: Abc_Print( -2, "\t-z : toggle using zero-cost replacements [default = %s]\n", fUseZeros? "yes": "no" ); Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle verbose printout of ODC computation [default = %s]\n", fVeryVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t-h : print the command usage\n\n"); + Abc_Print( -2, "\t When command line options '-P num', '-D num', and '-V num' are used,\n"); + Abc_Print( -2, "\t this command does not perform resubstitution; instead, it dumps a binary file\n"); + Abc_Print( -2, "\t containing 2^P resub problems, each containing 2^D-2 divs with support size V,\n"); + Abc_Print( -2, "\t while the last two divisors are the offset and the onset of the function\n"); + Abc_Print( -2, "\t (by default, the functions are completely specified; to get functions with don't-cares,\n"); + Abc_Print( -2, "\t the user has to use command-line option '-F num' to enable the limited ODC computation)\n"); + Abc_Print( -2, "\t-P : the log2 of the number of problems to be dumped [default = %d]\n", Log2Probs ); + Abc_Print( -2, "\t-D : the log2 of the number of divisors to be collected (4 <= num <= 7) [default = %d]\n", Log2Divs ); + Abc_Print( -2, "\t-V : the support size of the function (%d <= num <= %d) [default = %d]\n", RS_CUT_MIN, RS_CUT_MAX, nCutsMax ); return 1; } @@ -9196,11 +9248,11 @@ int Abc_CommandLutCasDec( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern Abc_Ntk_t * Abc_NtkLutCascadeGen( int nLutSize, int nStages, int nRails, int nShared, int fVerbose ); extern Abc_Ntk_t * Abc_NtkLutCascadeOne( Abc_Ntk_t * pNtk, int nLutSize, int nLuts, int nRails, int nIters, int nJRatio, int nZParam, int fXRail, int Seed, int fVerbose, int fVeryVerbose, char * pGuide, int nSubsets, int nBest ); - extern void Abc_NtkLutCascadeFile( char * pFileName, int nVarNum, int nLutSize, int nLuts, int nRails, int nIters, int nJRatio, int nZParam, int Seed, int fVerbose, int fVeryVerbose, int fPrintMyu, int fPrintLev, int fXRail, int nSubsets, int nBest ); + extern void Abc_NtkLutCascadeFile( char * pFileName, int nVarNum, int nLutSize, int nLuts, int nRails, int nIters, int nJRatio, int nZParam, int Seed, int fVerbose, int fVeryVerbose, int fPrintMyu, int fPrintLev, int fXRail, int nSubsets, int nBest, int fDump ); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc), * pNtkRes; char * pGuide = NULL, * pFileName = NULL; - int c, nVarNum = -1, nLutSize = 6, nStages = 8, nRails = 1, nShared = 2, Seed = 0, nIters = 10, nJRatio = -1, nZParam = 5, fGen = 0, fPrintMyu = 0, fPrintLev = 0, fXRail = 0, nSubsets = 0, nBest = 0, fVerbose = 0, fVeryVerbose = 0; + int c, nVarNum = -1, nLutSize = 6, nStages = 8, nRails = 1, nShared = 2, Seed = 0, nIters = 10, nJRatio = -1, nZParam = 5, fGen = 0, fPrintMyu = 0, fPrintLev = 0, fXRail = 0, nSubsets = 0, nBest = 0, fDump = 0, fVerbose = 0, fVeryVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KMRSCIZNGBFgmlxvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KMRSCIZNGBFgmlxdvwh" ) ) != EOF ) { switch ( c ) { @@ -9344,6 +9396,9 @@ int Abc_CommandLutCasDec( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'x': fXRail ^= 1; break; + case 'd': + fDump ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -9363,7 +9418,7 @@ int Abc_CommandLutCasDec( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "The number of variables should be given on the command line using switch \"-N \".\n" ); return 1; } - Abc_NtkLutCascadeFile( pFileName, nVarNum, nLutSize, nStages, nRails, nIters, nJRatio, nZParam, Seed, fVerbose, fVeryVerbose, fPrintMyu, fPrintLev, fXRail, nSubsets, nBest ); + Abc_NtkLutCascadeFile( pFileName, nVarNum, nLutSize, nStages, nRails, nIters, nJRatio, nZParam, Seed, fVerbose, fVeryVerbose, fPrintMyu, fPrintLev, fXRail, nSubsets, nBest, fDump ); return 0; } if ( fGen ) @@ -9410,7 +9465,7 @@ int Abc_CommandLutCasDec( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: lutcasdec [-KMRCSIZNGB ] [-F ] [-gmlxvwh]\n" ); + Abc_Print( -2, "usage: lutcasdec [-KMRCSIZNGB ] [-F ] [-gmlxdvwh]\n" ); Abc_Print( -2, "\t decomposes the primary output functions into LUT cascades\n" ); Abc_Print( -2, "\t-K : the number of LUT inputs [default = %d]\n", nLutSize ); Abc_Print( -2, "\t-M : the maximum delay (the number of stages) [default = %d]\n", nStages ); @@ -9428,6 +9483,7 @@ usage: Abc_Print( -2, "\t-m : toggle printing column multiplicity statistics [default = %s]\n", fPrintMyu? "yes": "no" ); Abc_Print( -2, "\t-l : toggle printing level counting statistics [default = %s]\n", fPrintLev? "yes": "no" ); Abc_Print( -2, "\t-x : toggle using extended cascade decomposition [default = %s]\n", fXRail? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle dumping non-decomposable functions into a file [default = %s]\n", fDump? "yes": "no" ); Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle additional verbose printout [default = %s]\n", fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); @@ -10635,14 +10691,14 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv ) Bmc_EsPar_t Pars, * pPars = &Pars; Bmc_EsParSetDefault( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "INKTFUSYiaorfgvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "NMKTFUSYiaorfgdvh" ) ) != EOF ) { switch ( c ) { - case 'I': + case 'N': if ( globalUtilOptind >= argc ) { - Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); goto usage; } pPars->nVars = atoi(argv[globalUtilOptind]); @@ -10650,10 +10706,10 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nVars < 0 ) goto usage; break; - case 'N': + case 'M': if ( globalUtilOptind >= argc ) { - Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); goto usage; } pPars->nNodes = atoi(argv[globalUtilOptind]); @@ -10739,6 +10795,9 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'g': pPars->fGlucose ^= 1; break; + case 'd': + pPars->fDumpBlif ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -10799,10 +10858,10 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: lutexact [-INKTFUS ] [-Y string] [-iaorfgvh] \n" ); + Abc_Print( -2, "usage: lutexact [-NMKTFUS ] [-Y string] [-iaorfgdvh] \n" ); Abc_Print( -2, "\t exact synthesis of I-input function using N K-input gates\n" ); - Abc_Print( -2, "\t-I : the number of input variables [default = %d]\n", pPars->nVars ); - Abc_Print( -2, "\t-N : the number of K-input nodes [default = %d]\n", pPars->nNodes ); + Abc_Print( -2, "\t-N : the number of input variables [default = %d]\n", pPars->nVars ); + Abc_Print( -2, "\t-M : the number of K-input nodes [default = %d]\n", pPars->nNodes ); Abc_Print( -2, "\t-K : the number of node fanins [default = %d]\n", pPars->nLutSize ); Abc_Print( -2, "\t-T : the runtime limit in seconds [default = %d]\n", pPars->RuntimeLim ); Abc_Print( -2, "\t-F : the number of random functions to try [default = unused]\n" ); @@ -10815,6 +10874,7 @@ usage: Abc_Print( -2, "\t-r : toggle synthesizing a single-rail cascade [default = %s]\n", pPars->fLutCascade ? "yes" : "no" ); Abc_Print( -2, "\t-f : toggle fixing LUT inputs in cascade mapping [default = %s]\n", pPars->fLutInFixed ? "yes" : "no" ); Abc_Print( -2, "\t-g : toggle using Glucose 3.0 by Gilles Audemard and Laurent Simon [default = %s]\n", pPars->fGlucose ? "yes" : "no" ); + Abc_Print( -2, "\t-d : toggle dumping decomposed networks into BLIF files [default = %s]\n", pPars->fDumpBlif ? "yes" : "no" ); Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", pPars->fVerbose ? "yes" : "no" ); Abc_Print( -2, "\t-h : print the command usage\n" ); Abc_Print( -2, "\t : truth table in hex notation\n" ); @@ -20931,17 +20991,17 @@ usage: ***********************************************************************/ int Abc_CommandRewire( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Abc_Ntk_t *Abc_ManRewire(Abc_Ntk_t *pNtk, Gia_Man_t *pExc, int nIters, float levelGrowRatio, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nMappedMode, int nDist, int nSeed, int fCheck, int fVerbose); + extern Abc_Ntk_t *Abc_ManRewire(Abc_Ntk_t *pNtk, Gia_Man_t *pExc, int nIters, float levelGrowRatio, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nMappedMode, int nDist, int fDch, int fTiming, int nSeed, int fCheck, int fVerbose); Abc_Ntk_t *pNtk, *pTemp; Gia_Man_t *pExc = NULL; FILE *pFile = NULL; - int c, nIters = 100000, nExpands = 128, nGrowth = 4, nDivs = -1, nFaninMax = 8, nSeed = 1, nTimeOut = 0, nVerbose = 1, nMode = 0, nMappedMode = 0, nDist = 0, fCheck = 0; + int c, nIters = 100000, nExpands = 128, nGrowth = 4, nDivs = -1, nFaninMax = 8, nSeed = 1, nTimeOut = 0, nVerbose = 1, nMode = 0, nMappedMode = 0, nDist = 0, fCheck = 0, fDch = 1, fTiming = 0; float nLevelGrowRatio = 0; Extra_UtilGetoptReset(); pNtk = Abc_FrameReadNtk(pAbc); - while ( ( c = Extra_UtilGetopt( argc, argv, "IEGDFSTMALRCVch" ) ) != EOF ) { + while ( ( c = Extra_UtilGetopt( argc, argv, "IEGDFSTMALRCVdtch" ) ) != EOF ) { switch ( c ) { case 'I': if ( globalUtilOptind >= argc ) @@ -21070,6 +21130,12 @@ int Abc_CommandRewire( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'c': fCheck ^= 1; break; + case 'd': + fDch ^= 1; + break; + case 't': + fTiming ^= 1; + break; case 'h': default: goto usage; @@ -21087,16 +21153,16 @@ int Abc_CommandRewire( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( nMode == 0 && !Abc_NtkIsStrash(pNtk) ) { - Abc_Print( -1, "Rewiring works only for the AIG representation (run \"strash\").\n" ); + Abc_Print( -1, "Rewiring operates only on specific network representations. Use \"strash\" to apply it to an AIG, or add the \"-M 1\" flag to enable it for a mapped network.\n" ); return 1; } - if ( nMode >= 1 && Abc_FrameReadLibGen2() == NULL ) + if ( nMode == 1 && Abc_FrameReadLibGen2() == NULL ) { Abc_Print( -1, "Library is not available.\n" ); return 1; } - pTemp = Abc_ManRewire( pNtk, pExc, nIters, nLevelGrowRatio, nExpands, nGrowth, nDivs, nFaninMax, nTimeOut, nMode, nMappedMode, nDist, nSeed, fCheck, nVerbose ); + pTemp = Abc_ManRewire( pNtk, pExc, nIters, nLevelGrowRatio, nExpands, nGrowth, nDivs, nFaninMax, nTimeOut, nMode, nMappedMode, nDist, fDch, fTiming, nSeed, fCheck, nVerbose ); if ( pExc ) Gia_ManStop( pExc ); Abc_FrameReplaceCurrentNetwork( pAbc, pTemp ); @@ -21111,13 +21177,15 @@ usage: Abc_Print( -2, "\t-F : the limit on the fanin count at a node [default = %d]\n", nFaninMax); Abc_Print( -2, "\t-L : localization distances (0: unlimited) [default = %d]\n", nDist); Abc_Print( -2, "\t-R : level constraint (0: unlimited, 1: preserve level) [default = %g]\n", nLevelGrowRatio); - Abc_Print( -2, "\t-M : optimization target [default = %s]\n", nMode ? "area" : "AIG node" ); + Abc_Print( -2, "\t-M : optimization target [default = %s]\n", nMode ? "mapped" : "AIG" ); Abc_Print( -2, "\t-A : mapper (0: amap, 1: &nf, 2: &simap) (experimental) [default = %d]\n", nMappedMode ); Abc_Print( -2, "\t-C : AIGER specifying external cares\n"); Abc_Print( -2, "\t-S : the random seed (0: random, >= 1: user defined) [default = %d]\n", nSeed ); Abc_Print( -2, "\t-T : the timeout in seconds (0: unlimited) [default = %d]\n", nTimeOut ); Abc_Print( -2, "\t-V : the verbosity level [default = %d]\n", nVerbose ); - Abc_Print( -2, "\t-c : check the equivalence [default = %s]\n", fCheck ? "yes" : "no" ); + Abc_Print( -2, "\t-c : check the equivalence [default = %s]\n", fCheck ? "yes" : "no" ); + Abc_Print( -2, "\t-d : toggle perform \"dch\" before mapping [default = %s]\n", fDch ? "yes" : "no" ); + Abc_Print( -2, "\t-t : toggle timing-driven rewiring [default = %s]\n", fTiming ? "yes" : "no" ); Abc_Print( -2, "\t-h : prints the command usage\n" ); Abc_Print( -2, "\n\tThis command was contributed by Jiun-Hao Chen from National Taiwan University.\n" ); return 1; @@ -21436,7 +21504,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) If_ManSetDefaultPars( pPars ); pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut(); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYUZDEWSJqaflepmrsdbgxyzuojiktncvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYUZDEWSJqalepmrsdbgxyzuojiktncfvh" ) ) != EOF ) { switch ( c ) { @@ -21647,9 +21715,9 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'r': pPars->fExpRed ^= 1; break; - case 'f': - pPars->fFancy ^= 1; - break; + //case 'f': + // pPars->fFancy ^= 1; + // break; case 'l': pPars->fLatchPaths ^= 1; break; @@ -21704,6 +21772,9 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'c': pPars->fUseTtPerm ^= 1; break; + case 'f': + pPars->fDumpFile ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -22015,7 +22086,7 @@ usage: sprintf(LutSize, "library" ); else sprintf(LutSize, "%d", pPars->nLutSize ); - Abc_Print( -2, "usage: if [-KCFAGRNTXYUZ num] [-DEW float] [-SJ str] [-qarlepmsdbgxyuojiktnczvh]\n" ); + Abc_Print( -2, "usage: if [-KCFAGRNTXYUZ num] [-DEW float] [-SJ str] [-qarlepmsdbgxyuojiktnczfvh]\n" ); Abc_Print( -2, "\t performs FPGA technology mapping of the network\n" ); Abc_Print( -2, "\t-K num : the number of LUT inputs (2 < num < %d) [default = %s]\n", IF_MAX_LUTSIZE+1, LutSize ); Abc_Print( -2, "\t-C num : the max number of priority cuts (0 < num < 2^12) [default = %d]\n", pPars->nCutsMax ); @@ -22056,6 +22127,7 @@ usage: Abc_Print( -2, "\t-n : toggles computing DSDs of the cut functions [default = %s]\n", pPars->fUseDsd? "yes": "no" ); Abc_Print( -2, "\t-c : toggles computing truth tables in a new way [default = %s]\n", pPars->fUseTtPerm? "yes": "no" ); Abc_Print( -2, "\t-z : toggles deriving LUTs when mapping into LUT structures [default = %s]\n", pPars->fDeriveLuts? "yes": "no" ); + Abc_Print( -2, "\t-f : toggles dumping truth tables into a binary file [default = %s]\n", pPars->fDumpFile? "yes": "no" ); Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : prints the command usage\n"); return 1; @@ -39781,13 +39853,16 @@ int Abc_CommandAbc9Append( Abc_Frame_t * pAbc, int argc, char ** argv ) char * FileName, * pTemp; char ** pArgvNew; int nArgcNew; - int c; + int c, fShareCis = 0; int fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ivh" ) ) != EOF ) { switch ( c ) { + case 'i': + fShareCis ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -39827,14 +39902,20 @@ int Abc_CommandAbc9Append( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Reading AIGER has failed.\n" ); return 0; } + if ( fShareCis && Gia_ManCiNum(pAbc->pGia) != Gia_ManCiNum(pSecond) ) + { + Abc_Print( -1, "The AIGs have different number of combinational inputs.\n" ); + return 0; + } // compute the miter - Gia_ManDupAppend( pAbc->pGia, pSecond ); + Gia_ManDupAppend( pAbc->pGia, pSecond, fShareCis ); Gia_ManStop( pSecond ); return 0; usage: - Abc_Print( -2, "usage: &append [-vh] \n" ); + Abc_Print( -2, "usage: &append [-ivh] \n" ); Abc_Print( -2, "\t appends to the current AIG using new PIs and POs\n" ); + Abc_Print( -2, "\t-i : toggle sharing combinational inputs [default = %s]\n", fShareCis? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\t : AIGER file with the design to miter\n"); @@ -46700,14 +46781,14 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Rewire( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Gia_Man_t *Gia_ManRewire(Gia_Man_t *pGia, Gia_Man_t *pExc, int nIters, float levelGrowRatio, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nMappedMode, int nDist, int nSeed, int fCheck, int fChoices, int fVerbose); + extern Gia_Man_t *Gia_ManRewire(Gia_Man_t *pGia, Gia_Man_t *pExc, int nIters, float levelGrowRatio, int nExpands, int nGrowth, int nDivs, int nFaninMax, int nTimeOut, int nMode, int nMappedMode, int nDist, int fDch, int fTiming, int nSeed, int fCheck, int fChoices, int fVerbose); FILE *pFile = NULL; Gia_Man_t *pTemp, *pExc = NULL; - int c, nIters = 100000, nExpands = 128, nGrowth = 4, nDivs = -1, nFaninMax = 8, nSeed = 1, nTimeOut = 0, nVerbose = 1, nMode = 0, nMappedMode = 0, nDist = 0, fCheck = 0, fChoices = 0; + int c, nIters = 100000, nExpands = 128, nGrowth = 4, nDivs = -1, nFaninMax = 8, nSeed = 1, nTimeOut = 0, nVerbose = 1, nMode = 0, nMappedMode = 0, nDist = 0, fCheck = 0, fChoices = 0, fDch = 1, fTiming = 0; float nLevelGrowRatio = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "IEGDFSTMALRCVcsh" ) ) != EOF ) { + while ( ( c = Extra_UtilGetopt( argc, argv, "IEGDFSTMALRCVcsdth" ) ) != EOF ) { switch ( c ) { case 'I': if ( globalUtilOptind >= argc ) @@ -46839,6 +46920,12 @@ int Abc_CommandAbc9Rewire( Abc_Frame_t * pAbc, int argc, char ** argv ) case 's': fChoices ^= 1; break; + case 'd': + fDch ^= 1; + break; + case 't': + fTiming ^= 1; + break; case 'h': default: goto usage; @@ -46854,13 +46941,13 @@ int Abc_CommandAbc9Rewire( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Empty GIA network.\n" ); return 1; } - if ( nMode >= 1 && Abc_FrameReadLibGen2() == NULL ) + if ( nMode == 1 && Abc_FrameReadLibGen2() == NULL ) { Abc_Print( -1, "Library is not available.\n" ); return 1; } - pTemp = Gia_ManRewire( pAbc->pGia, pExc, nIters, nLevelGrowRatio, nExpands, nGrowth, nDivs, nFaninMax, nTimeOut, nMode, nMappedMode, nDist, nSeed, fCheck, fChoices, nVerbose ); + pTemp = Gia_ManRewire( pAbc->pGia, pExc, nIters, nLevelGrowRatio, nExpands, nGrowth, nDivs, nFaninMax, nTimeOut, nMode, nMappedMode, nDist, fDch, fTiming, nSeed, fCheck, fChoices, nVerbose ); if ( pExc ) Gia_ManStop( pExc ); Abc_FrameUpdateGia( pAbc, pTemp ); @@ -46876,14 +46963,16 @@ usage: Abc_Print( -2, "\t-F : the limit on the fanin count at a node [default = %d]\n", nFaninMax); Abc_Print( -2, "\t-L : localization distances (0: unlimited) [default = %d]\n", nDist); Abc_Print( -2, "\t-R : level constraint (0: unlimited, 1: preserve level) [default = %g]\n", nLevelGrowRatio); - Abc_Print( -2, "\t-M : optimization target [default = %s]\n", nMode ? "area" : "AIG node" ); + Abc_Print( -2, "\t-M : optimization target [default = %s]\n", nMode ? "mapped" : "aig" ); Abc_Print( -2, "\t-A : mapper (0: amap, 1: &nf, 2: &simap) (experimental) [default = %d]\n", nMappedMode ); Abc_Print( -2, "\t-C : AIGER specifying external cares\n"); Abc_Print( -2, "\t-S : the random seed (0: random, >= 1: user defined) [default = %d]\n", nSeed ); Abc_Print( -2, "\t-T : the timeout in seconds (0: unlimited) [default = %d]\n", nTimeOut ); Abc_Print( -2, "\t-V : the verbosity level [default = %d]\n", nVerbose ); - Abc_Print( -2, "\t-c : check the equivalence [default = %s]\n", fCheck ? "yes" : "no" ); - Abc_Print( -2, "\t-s : toggle accumulating structural choices [default = %s]\n", fChoices ? "yes" : "no" ); + Abc_Print( -2, "\t-c : check the equivalence [default = %s]\n", fCheck ? "yes" : "no" ); + Abc_Print( -2, "\t-s : toggle accumulating structural choices [default = %s]\n", fChoices ? "yes" : "no" ); + Abc_Print( -2, "\t-d : toggle using \"dch\" before mapping [default = %s]\n", fDch ? "yes" : "no" ); + Abc_Print( -2, "\t-t : toggle timing-driven re-wiring [default = %s]\n", fTiming ? "yes" : "no" ); Abc_Print( -2, "\t-h : prints the command usage\n" ); Abc_Print( -2, "\n\tThis command was contributed by Jiun-Hao Chen from National Taiwan University.\n" ); return 1; @@ -47479,8 +47568,8 @@ usage: Abc_Print( -2, "\t-f : toggle using lighter logic synthesis [default = %s]\n", pPars->fLightSynth? "yes": "no" ); Abc_Print( -2, "\t-r : toggle skipping choices with redundant support [default = %s]\n", pPars->fSkipRedSupp? "yes": "no" ); Abc_Print( -2, "\t-e : toggle computing and merging equivalences [default = %s]\n", fEquiv? "yes": "no" ); - Abc_Print( -2, "\t-m : toggle minimizing logic level after merging equivalences [default = %s]\n", fRandom? "yes": "no" ); - Abc_Print( -2, "\t-n : toggle selecting random choices while merging equivalences [default = %s]\n", fMinLevel? "yes": "no" ); + Abc_Print( -2, "\t-m : toggle minimizing logic level after merging equivalences [default = %s]\n", fMinLevel? "yes": "no" ); + Abc_Print( -2, "\t-n : toggle selecting random choices while merging equivalences [default = %s]\n", fRandom? "yes": "no" ); Abc_Print( -2, "\t-g : toggle using GIA to prove equivalences [default = %s]\n", pPars->fUseGia? "yes": "no" ); Abc_Print( -2, "\t-c : toggle using circuit-based SAT vs. MiniSat [default = %s]\n", pPars->fUseCSat? "yes": "no" ); Abc_Print( -2, "\t-x : toggle using new choice computation [default = %s]\n", pPars->fUseNew? "yes": "no" ); @@ -53619,10 +53708,10 @@ usage: ***********************************************************************/ int Abc_CommandAbc9StochSyn( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Gia_ManStochSyn( int nSuppMax, int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript, int nProcs ); - int c, nSuppMax = 0, nMaxSize = 1000, nIters = 10, TimeOut = 0, Seed = 0, nProcs = 1, fVerbose = 0; char * pScript; + extern void Gia_ManStochSyn( int nSuppMax, int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript, int nProcs, int fDelayOpt ); + int c, nSuppMax = 0, nMaxSize = 1000, nIters = 10, TimeOut = 0, Seed = 0, nProcs = 1, fDelayOpt = 0, fVerbose = 0; char * pScript; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "NMITSPvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "NMITSPdvh" ) ) != EOF ) { switch ( c ) { @@ -53692,6 +53781,9 @@ int Abc_CommandAbc9StochSyn( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nProcs < 0 ) goto usage; break; + case 'd': + fDelayOpt ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -53712,19 +53804,20 @@ int Abc_CommandAbc9StochSyn( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } pScript = Abc_UtilStrsav( argv[globalUtilOptind] ); - Gia_ManStochSyn( nSuppMax, nMaxSize, nIters, TimeOut, Seed, fVerbose, pScript, nProcs ); + Gia_ManStochSyn( nSuppMax, nMaxSize, nIters, TimeOut, Seed, fVerbose, pScript, nProcs, fDelayOpt ); ABC_FREE( pScript ); return 0; usage: - Abc_Print( -2, "usage: &stochsyn [-NMITSP ] [-tvh]