diff --git a/src/rmp/BUILD b/src/rmp/BUILD index 861fbb7bab..dc83541cf9 100644 --- a/src/rmp/BUILD +++ b/src/rmp/BUILD @@ -18,8 +18,14 @@ cc_library( "src/annealing_strategy.h", "src/delay_optimization_strategy.cpp", "src/delay_optimization_strategy.h", + "src/genetic_strategy.cpp", + "src/genetic_strategy.h", + "src/gia.cpp", + "src/gia.h", "src/logic_optimization_strategy.h", "src/resynthesis_strategy.h", + "src/slack_tuning_strategy.cpp", + "src/slack_tuning_strategy.h", "src/utils.cpp", "src/utils.h", "src/zero_slack_strategy.cpp", @@ -52,6 +58,9 @@ cc_library( "@boost.optional", "@boost.phoenix", "@boost.spirit", + "@com_google_absl//absl/base:core_headers", + "@com_google_absl//absl/hash", + "@com_google_absl//absl/random", ], ) diff --git a/src/rmp/README.md b/src/rmp/README.md index 63f29aa4b9..4d92a665df 100644 --- a/src/rmp/README.md +++ b/src/rmp/README.md @@ -96,6 +96,45 @@ resynth_annealing | `-revert_after` | After the given number of iterations that worsen slack, revert to best found solution. | | `-initial_ops` | Size of the initial random solution (number of commands in the script for ABC). | +### Resynth with genetic slack tuning + +Resynthesize parts of the design with an ABC script found via genetic algorithm. +An individual in a population is a series of operations on ABC's internal AIG data structure. +Each such operation is considered a gene. Genotype can be changed by a mutation with operations such +as adding, removing or swapping genes with a `mut_prob` probability. Individual can also be changed +by crossing two genes together with a `cross_prob` probability. +The optimization function is defined as the worst slack. + +```tcl +resynth_genetic + [-corner corner] + [-slack_threshold slack_threshold] + [-seed seed] + [-pop_size pop_size] + [-mut_prob mut_prob] + [-cross_prob cross_prob] + [-tourn_prob tourn_prob] + [-tourn_size tourn_size] + [-iters iters] + [-initial_ops initial_ops] +``` + +#### Options + +| Switch Name | Description | +| ----- | ----- | +| `-corner` | Process corner to use. | +| `-slack_threshold` | Specifies a (setup) timing slack value below which timing paths need to be analyzed for restructuring. The default value is `0`. | +| `-seed` | Seed to use for randomness. | +| `-pop_size` | Population size. | +| `-mut_prob` | Probability of applying mutation operator. | +| `-cross_prob` | Probability of applying crossover operator. | +| `-tourn_prob` | Tournament probability. | +| `-tourn_size` | Tournament size. | +| `-iters` | Number of iterations to run genetic algorithm. | +| `-initial_ops` | Size of the initial random solution (number of commands in the script for ABC). | + + ## Example scripts Example scripts on running `rmp` for a sample design of `gcd` as follows: diff --git a/src/rmp/include/rmp/Restructure.h b/src/rmp/include/rmp/Restructure.h index 84a8d7251f..06f5d46c18 100644 --- a/src/rmp/include/rmp/Restructure.h +++ b/src/rmp/include/rmp/Restructure.h @@ -71,6 +71,7 @@ class Restructure void reset(); void resynth(sta::Corner* corner); void resynthAnnealing(sta::Corner* corner); + void resynthGenetic(sta::Corner* corner); void run(char* liberty_file_name, float slack_threshold, unsigned max_depth, @@ -88,6 +89,23 @@ class Restructure annealing_revert_after_ = revert_after; } void setAnnealingInitialOps(unsigned ops) { annealing_init_ops_ = ops; } + void setGeneticSeed(std::mt19937::result_type seed) { genetic_seed_ = seed; } + void setGeneticPopSize(unsigned pop_size) { genetic_pop_size_ = pop_size; } + void setGeneticMutProb(float mut_prob) { genetic_mut_prob_ = mut_prob; } + void setGeneticCrossProb(float cross_prob) + { + genetic_cross_prob_ = cross_prob; + } + void setGeneticTournSize(unsigned tourn_size) + { + genetic_tourn_size_ = tourn_size; + } + void setGeneticTournProb(float tourn_prob) + { + genetic_tourn_prob_ = tourn_prob; + } + void setGeneticIters(unsigned iters) { genetic_iters_ = iters; } + void setGeneticInitialOps(unsigned ops) { genetic_init_ops_ = ops; } void setSlackThreshold(sta::Slack thresh) { slack_threshold_ = thresh; } void setMode(const char* mode_name); void setTieLoPort(sta::LibertyPort* loport); @@ -131,6 +149,17 @@ class Restructure unsigned annealing_iters_ = 100; std::optional annealing_revert_after_; unsigned annealing_init_ops_ = 10; + + // Genetic + std::optional genetic_seed_; + unsigned genetic_pop_size_ = 4; + float genetic_mut_prob_ = 0.5; + float genetic_cross_prob_ = 0.5; + unsigned genetic_tourn_size_ = 4; + float genetic_tourn_prob_ = 0.8; + unsigned genetic_iters_ = 10; + unsigned genetic_init_ops_ = 10; + sta::Slack slack_threshold_ = 0; std::string input_blif_file_name_; diff --git a/src/rmp/src/CMakeLists.txt b/src/rmp/src/CMakeLists.txt index a79cad230d..89d7e0f288 100644 --- a/src/rmp/src/CMakeLists.txt +++ b/src/rmp/src/CMakeLists.txt @@ -16,6 +16,9 @@ add_library(rmp_lib Restructure.cpp annealing_strategy.cpp delay_optimization_strategy.cpp + genetic_strategy.cpp + gia.cpp + slack_tuning_strategy.cpp utils.cpp zero_slack_strategy.cpp ) @@ -48,6 +51,8 @@ target_include_directories(rmp target_include_directories(rmp_lib PUBLIC ../include + PRIVATE + . ) target_link_libraries(rmp_lib @@ -59,6 +64,7 @@ target_link_libraries(rmp_lib utl_lib cut ${ABC_LIBRARY} + absl_hash ) target_link_libraries(rmp diff --git a/src/rmp/src/Restructure.cpp b/src/rmp/src/Restructure.cpp index 675ad8cf72..1f17dbc00d 100644 --- a/src/rmp/src/Restructure.cpp +++ b/src/rmp/src/Restructure.cpp @@ -28,6 +28,7 @@ #include "cut/blif.h" #include "db_sta/dbNetwork.hh" #include "db_sta/dbSta.hh" +#include "genetic_strategy.h" #include "odb/db.h" #include "rsz/Resizer.hh" #include "sta/Delay.hh" @@ -105,6 +106,22 @@ void Restructure::resynthAnnealing(sta::Corner* corner) open_sta_, name_generator_, resizer_, logger_); } +void Restructure::resynthGenetic(sta::Corner* corner) +{ + GeneticStrategy genetic_strategy(corner, + slack_threshold_, + genetic_seed_, + genetic_pop_size_, + genetic_mut_prob_, + genetic_cross_prob_, + genetic_tourn_size_, + genetic_tourn_prob_, + genetic_iters_, + genetic_init_ops_); + genetic_strategy.OptimizeDesign( + open_sta_, name_generator_, resizer_, logger_); +} + void Restructure::run(char* liberty_file_name, float slack_threshold, unsigned max_depth, diff --git a/src/rmp/src/annealing_strategy.cpp b/src/rmp/src/annealing_strategy.cpp index aa8402df3c..1e68e39a90 100644 --- a/src/rmp/src/annealing_strategy.cpp +++ b/src/rmp/src/annealing_strategy.cpp @@ -3,313 +3,40 @@ #include "annealing_strategy.h" -#include - -#include #include +#include #include #include +#include +#include #include -#include "aig/gia/gia.h" -#include "aig/gia/giaAig.h" -#include "base/abc/abc.h" -#include "base/main/main.h" #include "cut/abc_library_factory.h" -#include "cut/logic_cut.h" -#include "cut/logic_extractor.h" #include "db_sta/dbNetwork.hh" #include "db_sta/dbSta.hh" -#include "map/if/if.h" -#include "map/scl/sclSize.h" -#include "misc/vec/vecPtr.h" +#include "gia.h" #include "odb/db.h" -#include "proof/dch/dch.h" #include "rsz/Resizer.hh" +#include "slack_tuning_strategy.h" #include "sta/Delay.hh" #include "sta/Graph.hh" -#include "sta/GraphDelayCalc.hh" #include "sta/MinMax.hh" -#include "sta/Search.hh" -#include "utils.h" #include "utl/Logger.h" -#include "utl/SuppressStdout.h" #include "utl/deleter.h" #include "utl/unique_name.h" -namespace abc { -extern Abc_Ntk_t* Abc_NtkFromAigPhase(Aig_Man_t* pMan); -extern Abc_Ntk_t* Abc_NtkFromCellMappedGia(Gia_Man_t* p, int fUseBuffs); -extern Abc_Ntk_t* Abc_NtkFromDarChoices(Abc_Ntk_t* pNtkOld, Aig_Man_t* pMan); -extern Abc_Ntk_t* Abc_NtkFromMappedGia(Gia_Man_t* p, - int fFindEnables, - int fUseBuffs); -extern Abc_Ntk_t* Abc_NtkMap(Abc_Ntk_t* pNtk, - Mio_Library_t* userLib, - double DelayTarget, - double AreaMulti, - double DelayMulti, - float LogFan, - float Slew, - float Gain, - int nGatesMin, - int fRecovery, - int fSwitching, - int fSkipFanout, - int fUseProfile, - int fUseBuffs, - int fVerbose); -extern Aig_Man_t* Abc_NtkToDar(Abc_Ntk_t* pNtk, int fExors, int fRegisters); -extern Aig_Man_t* Abc_NtkToDarChoices(Abc_Ntk_t* pNtk); -extern Gia_Man_t* Gia_ManAigSynch2(Gia_Man_t* p, - void* pPars, - int nLutSize, - int nRelaxRatio); -extern Gia_Man_t* Gia_ManCheckFalse(Gia_Man_t* p, - int nSlackMax, - int nTimeOut, - int fVerbose, - int fVeryVerbose); -extern Vec_Ptr_t* Abc_NtkCollectCiNames(Abc_Ntk_t* pNtk); -extern Vec_Ptr_t* Abc_NtkCollectCoNames(Abc_Ntk_t* pNtk); -extern void Abc_NtkRedirectCiCo(Abc_Ntk_t* pNtk); -} // namespace abc namespace rmp { using utl::RMP; -static void replaceGia(abc::Gia_Man_t*& gia, abc::Gia_Man_t* new_gia) -{ - if (gia == new_gia) { - return; - } - if (gia->vNamesIn && !new_gia->vNamesIn) { - std::swap(gia->vNamesIn, new_gia->vNamesIn); - } - if (gia->vNamesOut && !new_gia->vNamesOut) { - std::swap(gia->vNamesOut, new_gia->vNamesOut); - } - if (gia->vNamesNode && !new_gia->vNamesNode) { - std::swap(gia->vNamesNode, new_gia->vNamesNode); - } - abc::Gia_ManStop(gia); - gia = new_gia; -} - -void AnnealingStrategy::OptimizeDesign(sta::dbSta* sta, - utl::UniqueName& name_generator, - rsz::Resizer* resizer, - utl::Logger* logger) +std::vector AnnealingStrategy::RunStrategy( + const std::vector& all_ops, + const std::vector& candidate_vertices, + cut::AbcLibrary& abc_library, + sta::dbSta* sta, + utl::UniqueName& name_generator, + rsz::Resizer* resizer, + utl::Logger* logger) { - sta->ensureGraph(); - sta->ensureLevelized(); - sta->searchPreamble(); - sta->ensureClkNetwork(); - auto block = sta->db()->getChip()->getBlock(); - - auto candidate_vertices = GetEndpoints(sta, resizer, slack_threshold_); - if (candidate_vertices.empty()) { - logger->info(utl::RMP, - 51, - "All endpoints have slack above threshold, nothing to do."); - return; - } - - cut::AbcLibraryFactory factory(logger); - factory.AddDbSta(sta); - factory.AddResizer(resizer); - factory.SetCorner(corner_); - cut::AbcLibrary abc_library = factory.Build(); - - // GIA ops as lambdas - // All the magic numbers are defaults from abc/src/base/abci/abc.c - // Or from the ORFS abc_speed script - std::vector all_ops - = {[&](auto& gia) { - // &st - debugPrint(logger, RMP, "annealing", 1, "Starting rehash"); - replaceGia(gia, Gia_ManRehash(gia, false)); - }, - - [&](auto& gia) { - // &dch - if (!gia->pReprs) { - debugPrint(logger, - RMP, - "annealing", - 1, - "Computing choices before equiv reduce"); - abc::Dch_Pars_t pars = {}; - Dch_ManSetDefaultParams(&pars); - replaceGia(gia, Gia_ManPerformDch(gia, &pars)); - } - debugPrint(logger, RMP, "annealing", 1, "Starting equiv reduce"); - replaceGia(gia, Gia_ManEquivReduce(gia, true, false, false, false)); - }, - - [&](auto& gia) { - // &syn2 - debugPrint(logger, RMP, "annealing", 1, "Starting syn2"); - replaceGia(gia, - Gia_ManAigSyn2(gia, false, true, 0, 20, 0, false, false)); - }, - - [&](auto& gia) { - // &syn3 - debugPrint(logger, RMP, "annealing", 1, "Starting syn3"); - replaceGia(gia, Gia_ManAigSyn3(gia, false, false)); - }, - - [&](auto& gia) { - // &syn4 - debugPrint(logger, RMP, "annealing", 1, "Starting syn4"); - replaceGia(gia, Gia_ManAigSyn4(gia, false, false)); - }, - - [&](auto& gia) { - // &retime - debugPrint(logger, RMP, "annealing", 1, "Starting retime"); - replaceGia(gia, Gia_ManRetimeForward(gia, 100, false)); - }, - - [&](auto& gia) { - // &dc2 - debugPrint(logger, RMP, "annealing", 1, "Starting heavy rewriting"); - replaceGia(gia, Gia_ManCompress2(gia, true, false)); - }, - - [&](auto& gia) { - // &b - debugPrint(logger, RMP, "annealing", 1, "Starting &b"); - replaceGia( - gia, Gia_ManAreaBalance(gia, false, ABC_INFINITY, false, false)); - }, - - [&](auto& gia) { - // &b -d - debugPrint(logger, RMP, "annealing", 1, "Starting &b -d"); - replaceGia(gia, Gia_ManBalance(gia, false, false, false)); - }, - - [&](auto& gia) { - // &false - debugPrint( - logger, RMP, "annealing", 1, "Starting false path elimination"); - utl::SuppressStdout nostdout(logger); - replaceGia(gia, Gia_ManCheckFalse(gia, 0, 0, false, false)); - }, - - [&](auto& gia) { - // &reduce - if (!gia->pReprs) { - debugPrint(logger, - RMP, - "annealing", - 1, - "Computing choices before equiv reduce"); - abc::Dch_Pars_t pars = {}; - Dch_ManSetDefaultParams(&pars); - replaceGia(gia, Gia_ManPerformDch(gia, &pars)); - } - debugPrint( - logger, RMP, "annealing", 1, "Starting equiv reduce and remap"); - replaceGia(gia, Gia_ManEquivReduceAndRemap(gia, true, false)); - }, - - [&](auto& gia) { - // &if -g -K 6 - if (Gia_ManHasMapping(gia)) { - debugPrint(logger, - RMP, - "annealing", - 1, - "GIA has mapping - rehashing before mapping"); - replaceGia(gia, Gia_ManRehash(gia, false)); - } - abc::If_Par_t pars = {}; - Gia_ManSetIfParsDefault(&pars); - pars.fDelayOpt = true; - pars.nLutSize = 6; - pars.fTruth = true; - pars.fCutMin = true; - pars.fExpRed = false; - debugPrint(logger, RMP, "annealing", 1, "Starting SOP balancing"); - replaceGia(gia, Gia_ManPerformMapping(gia, &pars)); - }, - - [&](auto& gia) { - // &synch2 - abc::Dch_Pars_t pars = {}; - Dch_ManSetDefaultParams(&pars); - pars.nBTLimit = 100; - debugPrint(logger, RMP, "annealing", 1, "Starting synch2"); - replaceGia(gia, Gia_ManAigSynch2(gia, &pars, 6, 20)); - }}; - /* Some ABC functions/commands that could be used, but crash in some - permutations: - * &nf. Call it like this: - namespace abc { - extern Gia_Man_t* Nf_ManPerformMapping(Gia_Man_t* pGia, - Jf_Par_t* pPars); - } - abc::Jf_Par_t pars = {}; - Nf_ManSetDefaultPars(&pars); - new_gia = Nf_ManPerformMapping(gia, &pars); - It crashes on a null pointer due to a missing time manager. We can make - the time manager: - gia->pManTime = abc::Tim_ManStart(Gia_ManCiNum(new_gia), - Gia_ManCoNum(new_gia)); - But then, an assert deep in &nf fails. - * &dsd. Call it like this: - namespace abc { - extern Gia_Man_t* Gia_ManCollapseTest(Gia_Man_t* p, int fVerbose); - } - new_gia = Gia_ManCollapseTest(gia, false); - An assert fails. - - Some functions/commands don't actually exist: - * &resub - * &reshape, &reshape -a - These are just stubs that return null. - */ - - // Computes a random neighbor of a given GIA op list - const auto neighbor = [&](std::vector ops) { - enum Move - { - ADD, - REMOVE, - SWAP, - COUNT - }; - Move move = ADD; - if (ops.size() > 1) { - move = Move(random_() % (COUNT)); - } - switch (move) { - case ADD: { - debugPrint(logger, RMP, "annealing", 2, "Adding a new GIA operation"); - size_t i = random_() % (ops.size() + 1); - size_t j = random_() % all_ops.size(); - ops.insert(ops.begin() + i, all_ops[j]); - } break; - case REMOVE: { - debugPrint(logger, RMP, "annealing", 2, "Removing a GIA operation"); - size_t i = random_() % ops.size(); - ops.erase(ops.begin() + i); - } break; - case SWAP: { - debugPrint( - logger, RMP, "annealing", 2, "Swapping adjacent GIA operations"); - size_t i = random_() % (ops.size() - 1); - std::swap(ops[i], ops[i + 1]); - } break; - case COUNT: - // unreachable - std::abort(); - } - return ops; - }; - // Initial solution and slack debugPrint(logger, RMP, @@ -322,27 +49,15 @@ void AnnealingStrategy::OptimizeDesign(sta::dbSta* sta, ops.push_back(all_ops[random_() % all_ops.size()]); } - // The magic numbers are defaults from abc/src/base/abci/abc.c - const size_t SEARCH_RESIZE_ITERS = 100; - const size_t FINAL_RESIZE_ITERS = 1000; - - odb::dbDatabase::beginEco(block); - - RunGia(sta, - candidate_vertices, - abc_library, - ops, - SEARCH_RESIZE_ITERS, - name_generator, - logger); + SolutionSlack sol_slack; + sol_slack.solution_ = ops; + auto* worst_vertex = sol_slack.Evaluate( + candidate_vertices, abc_library, corner_, sta, name_generator, logger); - odb::dbDatabase::endEco(block); - - float worst_slack; - sta::Vertex* worst_vertex; - sta->worstSlack(corner_, sta::MinMax::max(), worst_slack, worst_vertex); - - odb::dbDatabase::undoEco(block); + if (!sol_slack.worst_slack_) { + logger->error(RMP, 51, "Should be evaluated"); + } + float worst_slack = *sol_slack.worst_slack_; if (!temperature_) { sta::Delay required = sta->vertexRequired(worst_vertex, sta::MinMax::max()); @@ -356,8 +71,7 @@ void AnnealingStrategy::OptimizeDesign(sta::dbSta* sta, *temperature_, worst_slack); - float best_worst_slack = worst_slack; - auto best_ops = ops; + SolutionSlack best_sol{.solution_ = ops, .worst_slack_ = worst_slack}; size_t worse_iters = 0; for (unsigned i = 0; i < iterations_; i++) { @@ -366,8 +80,8 @@ void AnnealingStrategy::OptimizeDesign(sta::dbSta* sta, if (revert_after_ && worse_iters >= *revert_after_) { logger->info(RMP, 57, "Reverting to the best found solution"); - ops = best_ops; - worst_slack = best_worst_slack; + ops = best_sol.solution_; + worst_slack = *best_sol.worst_slack_; worse_iters = 0; } @@ -377,7 +91,7 @@ void AnnealingStrategy::OptimizeDesign(sta::dbSta* sta, "Iteration: {}, temperature: {}, best worst slack: {}", i + 1, current_temp, - best_worst_slack); + *best_sol.worst_slack_); } else { debugPrint(logger, RMP, @@ -386,28 +100,23 @@ void AnnealingStrategy::OptimizeDesign(sta::dbSta* sta, "Iteration: {}, temperature: {}, best worst slack: {}", i + 1, current_temp, - best_worst_slack); + best_sol.worst_slack_ ? *best_sol.worst_slack_ : 0); } - odb::dbDatabase::beginEco(block); + SolutionSlack s; + s.solution_ = ops; + auto new_ops = s.RandomNeighbor(all_ops, logger, random_); + sol_slack.solution_ = new_ops; - auto new_ops = neighbor(ops); - RunGia(sta, - candidate_vertices, - abc_library, - new_ops, - SEARCH_RESIZE_ITERS, - name_generator, - logger); + sol_slack.Evaluate( + candidate_vertices, abc_library, corner_, sta, name_generator, logger); - odb::dbDatabase::endEco(block); - - float worst_slack_new; - sta->worstSlack(corner_, sta::MinMax::max(), worst_slack_new, worst_vertex); - - odb::dbDatabase::undoEco(block); + if (!sol_slack.worst_slack_) { + logger->error(RMP, 55, "Should be evaluated"); + } + float worst_slack_new = *sol_slack.worst_slack_; - if (worst_slack_new < best_worst_slack) { + if (best_sol.worst_slack_ && worst_slack_new < *best_sol.worst_slack_) { worse_iters++; } else { worse_iters = 0; @@ -456,204 +165,12 @@ void AnnealingStrategy::OptimizeDesign(sta::dbSta* sta, ops = std::move(new_ops); worst_slack = worst_slack_new; - if (worst_slack > best_worst_slack) { - best_worst_slack = worst_slack; - best_ops = ops; + if (best_sol.worst_slack_ && worst_slack > *best_sol.worst_slack_) { + *best_sol.worst_slack_ = worst_slack; + best_sol.solution_ = ops; } } - - logger->info( - RMP, 55, "Resynthesis: End of simulated annealing, applying operations"); - logger->info(RMP, 56, "Resynthesis: Applying ABC operations"); - - // Apply the ops - RunGia(sta, - candidate_vertices, - abc_library, - best_ops, - FINAL_RESIZE_ITERS, - name_generator, - logger); + return best_sol.solution_; } -void AnnealingStrategy::RunGia( - sta::dbSta* sta, - const std::vector& candidate_vertices, - cut::AbcLibrary& abc_library, - const std::vector& gia_ops, - size_t resize_iters, - utl::UniqueName& name_generator, - utl::Logger* logger) -{ - sta::dbNetwork* network = sta->getDbNetwork(); - - // Disable incremental timing. - sta->graphDelayCalc()->delaysInvalid(); - sta->search()->arrivalsInvalid(); - sta->search()->endpointsInvalid(); - - cut::LogicExtractorFactory logic_extractor(sta, logger); - for (sta::Vertex* negative_endpoint : candidate_vertices) { - logic_extractor.AppendEndpoint(negative_endpoint); - } - - cut::LogicCut cut = logic_extractor.BuildLogicCut(abc_library); - - utl::UniquePtrWithDeleter mapped_abc_network - = cut.BuildMappedAbcNetwork(abc_library, network, logger); - - utl::UniquePtrWithDeleter current_network( - abc::Abc_NtkToLogic( - const_cast(mapped_abc_network.get())), - &abc::Abc_NtkDelete); - - { - auto library - = static_cast(mapped_abc_network->pManFunc); - - // Install library for NtkMap - abc::Abc_FrameSetLibGen(library); - - debugPrint(logger, - RMP, - "annealing", - 1, - "Mapped ABC network has {} nodes and {} POs.", - abc::Abc_NtkNodeNum(current_network.get()), - abc::Abc_NtkPoNum(current_network.get())); - - current_network->pManFunc = library; - abc::Gia_Man_t* gia = nullptr; - - { - debugPrint(logger, RMP, "annealing", 1, "Converting to GIA"); - auto ntk = current_network.get(); - assert(!Abc_NtkIsStrash(ntk)); - // derive comb GIA - auto strash = Abc_NtkStrash(ntk, false, true, false); - auto aig = Abc_NtkToDar(strash, false, false); - Abc_NtkDelete(strash); - gia = Gia_ManFromAig(aig); - Aig_ManStop(aig); - // perform undc/zero - auto inits = Abc_NtkCollectLatchValuesStr(ntk); - auto temp = gia; - gia = Gia_ManDupZeroUndc(gia, inits, 0, false, false); - Gia_ManStop(temp); - ABC_FREE(inits); - // copy names - gia->vNamesIn = abc::Abc_NtkCollectCiNames(ntk); - gia->vNamesOut = abc::Abc_NtkCollectCoNames(ntk); - } - - // Run all the given GIA ops - for (auto& op : gia_ops) { - op(gia); - } - - { - debugPrint(logger, RMP, "annealing", 1, "Converting GIA to network"); - abc::Extra_UtilGetoptReset(); - - if (Gia_ManHasCellMapping(gia)) { - current_network = WrapUnique(abc::Abc_NtkFromCellMappedGia(gia, false)); - } else if (Gia_ManHasMapping(gia) || gia->pMuxes) { - current_network = WrapUnique(Abc_NtkFromMappedGia(gia, false, false)); - } else { - if (Gia_ManHasDangling(gia) != 0) { - debugPrint( - logger, RMP, "annealing", 1, "Rehashing before conversion"); - replaceGia(gia, Gia_ManRehash(gia, false)); - } - assert(Gia_ManHasDangling(gia) == 0); - auto aig = Gia_ManToAig(gia, false); - current_network = WrapUnique(Abc_NtkFromAigPhase(aig)); - current_network->pName = abc::Extra_UtilStrsav(aig->pName); - Aig_ManStop(aig); - } - - assert(gia->vNamesIn); - for (int i = 0; i < abc::Abc_NtkCiNum(current_network.get()); i++) { - assert(i < Vec_PtrSize(gia->vNamesIn)); - abc::Abc_Obj_t* obj = abc::Abc_NtkCi(current_network.get(), i); - assert(obj); - Nm_ManDeleteIdName(current_network->pManName, obj->Id); - Abc_ObjAssignName( - obj, static_cast(Vec_PtrEntry(gia->vNamesIn, i)), nullptr); - } - assert(gia->vNamesOut); - for (int i = 0; i < abc::Abc_NtkCoNum(current_network.get()); i++) { - assert(i < Vec_PtrSize(gia->vNamesOut)); - abc::Abc_Obj_t* obj = Abc_NtkCo(current_network.get(), i); - assert(obj); - Nm_ManDeleteIdName(current_network->pManName, obj->Id); - assert(Abc_ObjIsPo(obj)); - Abc_ObjAssignName( - obj, static_cast(Vec_PtrEntry(gia->vNamesOut, i)), nullptr); - } - - // decouple CI/CO with the same name - if (!Abc_NtkIsStrash(current_network.get()) - && (gia->vNamesIn || gia->vNamesOut)) { - abc::Abc_NtkRedirectCiCo(current_network.get()); - } - - Gia_ManStop(gia); - } - - if (!Abc_NtkIsStrash(current_network.get())) { - current_network = WrapUnique( - abc::Abc_NtkStrash(current_network.get(), false, true, false)); - } - - { - utl::SuppressStdout nostdout(logger); - current_network = WrapUnique(abc::Abc_NtkMap(current_network.get(), - nullptr, - /*DelayTarget=*/1.0, - /*AreaMulti=*/0.0, - /*DelayMulti=*/2.5, - /*LogFan=*/0.0, - /*Slew=*/0.0, - /*Gain=*/250.0, - /*nGatesMin=*/0, - /*fRecovery=*/true, - /*fSwitching=*/false, - /*fSkipFanout=*/false, - /*fUseProfile=*/false, - /*fUseBuffs=*/false, - /*fVerbose=*/false)); - } - - abc::Abc_NtkCleanup(current_network.get(), /*fVerbose=*/false); - - current_network = WrapUnique(abc::Abc_NtkDupDfs(current_network.get())); - - if (resize_iters > 0) { - // All the magic numbers are defaults from abc/src/base/abci/abc.c - utl::SuppressStdout nostdout(logger); - abc::SC_SizePars pars = {}; - pars.nIters = resize_iters; - pars.nIterNoChange = 50; - pars.Window = 1; - pars.Ratio = 10; - pars.Notches = 1000; - pars.DelayUser = 0; - pars.DelayGap = 0; - pars.TimeOut = 0; - pars.BuffTreeEst = 0; - pars.BypassFreq = 0; - pars.fUseDept = true; - abc::Abc_SclUpsizePerform( - abc_library.abc_library(), current_network.get(), &pars, nullptr); - abc::Abc_SclDnsizePerform( - abc_library.abc_library(), current_network.get(), &pars, nullptr); - } - - current_network = WrapUnique(abc::Abc_NtkToNetlist(current_network.get())); - } - - cut.InsertMappedAbcNetwork( - current_network.get(), abc_library, network, name_generator, logger); -} } // namespace rmp diff --git a/src/rmp/src/annealing_strategy.h b/src/rmp/src/annealing_strategy.h index b7737aeeae..aab53e807f 100644 --- a/src/rmp/src/annealing_strategy.h +++ b/src/rmp/src/annealing_strategy.h @@ -3,25 +3,19 @@ #pragma once -#include -#include #include #include +#include #include "cut/abc_library_factory.h" -#include "db_sta/dbSta.hh" -#include "resynthesis_strategy.h" -#include "rsz/Resizer.hh" -#include "sta/Corner.hh" +#include "gia.h" +#include "slack_tuning_strategy.h" #include "sta/Delay.hh" -#include "utl/Logger.h" #include "utl/unique_name.h" namespace rmp { -using GiaOp = std::function; - -class AnnealingStrategy : public ResynthesisStrategy +class AnnealingStrategy final : public SlackTuningStrategy { public: explicit AnnealingStrategy(sta::Corner* corner, @@ -31,37 +25,28 @@ class AnnealingStrategy : public ResynthesisStrategy unsigned iterations, std::optional revert_after, unsigned initial_ops) - : corner_(corner), - slack_threshold_(slack_threshold), + : SlackTuningStrategy(corner, + slack_threshold, + seed, + iterations, + initial_ops), temperature_(temperature), - iterations_(iterations), - revert_after_(revert_after), - initial_ops_(initial_ops) + revert_after_(revert_after) { - if (seed) { - random_.seed(*seed); - } } - void OptimizeDesign(sta::dbSta* sta, - utl::UniqueName& name_generator, - rsz::Resizer* resizer, - utl::Logger* logger) override; - void RunGia(sta::dbSta* sta, - const std::vector& candidate_vertices, - cut::AbcLibrary& abc_library, - const std::vector& gia_ops, - size_t resize_iters, - utl::UniqueName& name_generator, - utl::Logger* logger); + + std::vector RunStrategy( + const std::vector& all_ops, + const std::vector& candidate_vertices, + cut::AbcLibrary& abc_library, + sta::dbSta* sta, + utl::UniqueName& name_generator, + rsz::Resizer* resizer, + utl::Logger* logger) override; private: - sta::Corner* corner_; - sta::Slack slack_threshold_; std::optional temperature_; - unsigned iterations_; std::optional revert_after_; - unsigned initial_ops_; - std::mt19937 random_; }; } // namespace rmp diff --git a/src/rmp/src/genetic_strategy.cpp b/src/rmp/src/genetic_strategy.cpp new file mode 100644 index 0000000000..d18e0e3c82 --- /dev/null +++ b/src/rmp/src/genetic_strategy.cpp @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2025-2025, The OpenROAD Authors + +#include "genetic_strategy.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/hash/hash.h" +#include "absl/random/random.h" +#include "cut/abc_library_factory.h" +#include "db_sta/dbNetwork.hh" +#include "db_sta/dbSta.hh" +#include "gia.h" +#include "rsz/Resizer.hh" +#include "slack_tuning_strategy.h" +#include "utl/Logger.h" +#include "utl/deleter.h" +#include "utl/unique_name.h" + +namespace rmp { +using utl::RMP; + +static void removeDuplicates(std::vector& population, + utl::Logger* logger) +{ + std::unordered_set> + taken; + population.erase( + std::ranges::begin(std::ranges::remove_if( + population, + [&taken, logger](const SolutionSlack& s) { + if (!taken.insert(s.solution_).second) { + debugPrint( + logger, RMP, "genetic", 2, "Removing: " + s.toString()); + return true; + } + debugPrint(logger, RMP, "genetic", 2, "Keeping: " + s.toString()); + return false; + })), + population.end()); +} + +std::vector GeneticStrategy::RunStrategy( + const std::vector& all_ops, + const std::vector& candidate_vertices, + cut::AbcLibrary& abc_library, + sta::dbSta* sta, + utl::UniqueName& name_generator, + rsz::Resizer* resizer, + utl::Logger* logger) +{ + if (pop_size_ <= 0) { + logger->error(RMP, 64, "Population size should be greater than 0"); + } + + // Initial solution and slack + debugPrint(logger, + RMP, + "population", + 1, + "Generating and evaluating the initial population"); + std::vector population(pop_size_); + for (auto& ind : population) { + ind.solution_.reserve(initial_ops_); + for (size_t i = 0; i < initial_ops_; i++) { + const auto idx = absl::Uniform(random_, 0, all_ops.size()); + ind.solution_.push_back(all_ops[idx]); + } + } + + for (auto& candidate : population) { + candidate.Evaluate( + candidate_vertices, abc_library, corner_, sta, name_generator, logger); + + debugPrint(logger, RMP, "genetic", 1, candidate.toString()); + } + + for (unsigned i = 0; i < iterations_; i++) { + logger->info(RMP, 65, "Resynthesis: Iteration {} of genetic algorithm", i); + unsigned generation_size = population.size(); + // Crossover + unsigned cross_size = std::max(cross_prob_ * generation_size, 1); + for (unsigned j = 0; j < cross_size; j++) { + auto rand1 = absl::Uniform(random_, 0, generation_size); + auto rand2 = absl::Uniform(random_, 0, generation_size); + if (rand1 == rand2) { + continue; + } + SolutionSlack::Type& parent1_sol = population[rand1].solution_; + SolutionSlack::Type& parent2_sol = population[rand2].solution_; + SolutionSlack::Type child_sol( + parent1_sol.begin(), parent1_sol.begin() + parent1_sol.size() / 2); + child_sol.insert(child_sol.end(), + parent2_sol.begin() + parent2_sol.size() / 2, + parent2_sol.end()); + SolutionSlack child_sol_slack; + child_sol_slack.solution_ = std::move(child_sol); + population.emplace_back(child_sol_slack); + } + // Mutations + unsigned mut_size = std::max(mut_prob_ * generation_size, 1); + for (unsigned j = 0; j < mut_size; j++) { + SolutionSlack sol_slack; + auto rand = absl::Uniform(random_, 0, generation_size); + sol_slack.solution_ + = population[rand].RandomNeighbor(all_ops, logger, random_); + population.emplace_back(sol_slack); + } + removeDuplicates(population, logger); + // Evaluation + for (auto& sol_slack : population) { + if (sol_slack.worst_slack_) { + continue; + } + sol_slack.Evaluate(candidate_vertices, + abc_library, + corner_, + sta, + name_generator, + logger); + } + // Selection + std::ranges::stable_sort( + population, std::greater{}, &SolutionSlack::worst_slack_); + std::vector newPopulation; + newPopulation.reserve(pop_size_); + for (int j = 0; j < pop_size_; j++) { + std::vector tournament(tourn_size_); + std::generate_n(tournament.begin(), tourn_size_, [&]() { + return absl::Uniform(random_, 0, population.size()); + }); + std::ranges::stable_sort(tournament); + tournament.erase(std::ranges::begin(std::ranges::unique(tournament)), + tournament.end()); + auto winner = std::ranges::find_if(tournament, [&](auto const& _) { + return absl::Bernoulli(random_, static_cast(tourn_prob_)); + }); + if (winner != tournament.end()) { + newPopulation.emplace_back(population[*winner]); + } + } + removeDuplicates(newPopulation, logger); + + if (newPopulation.empty()) { + newPopulation.emplace_back(population.front()); + } + + population = std::move(newPopulation); + + for (const auto& candidate : population) { + debugPrint(logger, RMP, "genetic", 1, candidate.toString()); + } + } + + auto best_it + = std::ranges::max_element(population, {}, &SolutionSlack::worst_slack_); + logger->info(RMP, + 66, + "Resynthesis: Best result is of individual {}", + std::distance(population.begin(), best_it)); + return best_it->solution_; +} +} // namespace rmp diff --git a/src/rmp/src/genetic_strategy.h b/src/rmp/src/genetic_strategy.h new file mode 100644 index 0000000000..c83763e889 --- /dev/null +++ b/src/rmp/src/genetic_strategy.h @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2025-2025, The OpenROAD Authors + +#pragma once + +#include +#include +#include + +#include "cut/abc_library_factory.h" +#include "gia.h" +#include "slack_tuning_strategy.h" +#include "sta/Delay.hh" +#include "utl/unique_name.h" + +namespace rmp { + +class GeneticStrategy final : public SlackTuningStrategy +{ + public: + explicit GeneticStrategy(sta::Corner* corner, + sta::Slack slack_threshold, + std::optional seed, + unsigned pop_size, + float mut_prob, + float cross_prob, + unsigned tourn_size, + float tourn_prob, + unsigned iterations, + unsigned initial_ops) + : SlackTuningStrategy(corner, + slack_threshold, + seed, + iterations, + initial_ops), + pop_size_(pop_size), + mut_prob_(mut_prob), + cross_prob_(cross_prob), + tourn_size_(tourn_size), + tourn_prob_(tourn_prob) + { + } + + std::vector RunStrategy( + const std::vector& all_ops, + const std::vector& candidate_vertices, + cut::AbcLibrary& abc_library, + sta::dbSta* sta, + utl::UniqueName& name_generator, + rsz::Resizer* resizer, + utl::Logger* logger) override; + + private: + unsigned pop_size_; + float mut_prob_; + float cross_prob_; + unsigned tourn_size_; + float tourn_prob_; +}; + +} // namespace rmp diff --git a/src/rmp/src/gia.cpp b/src/rmp/src/gia.cpp new file mode 100644 index 0000000000..f91fc5c82e --- /dev/null +++ b/src/rmp/src/gia.cpp @@ -0,0 +1,419 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2025-2025, The OpenROAD Authors + +#include "aig/gia/gia.h" + +#include +#include +#include +#include +#include + +#include "aig/aig/aig.h" +#include "aig/gia/giaAig.h" +#include "base/abc/abc.h" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wredundant-decls" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" +#pragma GCC diagnostic ignored "-Wunused-variable" +#include "map/if/if.h" +#pragma GCC diagnostic pop +#include "cut/abc_library_factory.h" +#include "cut/logic_cut.h" +#include "cut/logic_extractor.h" +#include "db_sta/dbNetwork.hh" +#include "db_sta/dbSta.hh" +#include "gia.h" +#include "map/mio/mio.h" +#include "map/scl/sclLib.h" +#include "map/scl/sclSize.h" +#include "misc/extra/extra.h" +#include "misc/nm/nm.h" +#include "misc/util/abc_global.h" +#include "misc/vec/vecPtr.h" +#include "odb/db.h" +#include "proof/dch/dch.h" +#include "sta/Graph.hh" +#include "sta/GraphDelayCalc.hh" +#include "sta/Search.hh" +#include "utils.h" +#include "utl/Logger.h" +#include "utl/SuppressStdout.h" +#include "utl/deleter.h" +#include "utl/unique_name.h" + +namespace abc { +extern Abc_Ntk_t* Abc_NtkFromAigPhase(Aig_Man_t* pMan); +extern Abc_Ntk_t* Abc_NtkFromCellMappedGia(Gia_Man_t* p, int fUseBuffs); +extern Abc_Ntk_t* Abc_NtkFromDarChoices(Abc_Ntk_t* pNtkOld, Aig_Man_t* pMan); +extern Abc_Ntk_t* Abc_NtkFromMappedGia(Gia_Man_t* p, + int fFindEnables, + int fUseBuffs); +extern Abc_Ntk_t* Abc_NtkMap(Abc_Ntk_t* pNtk, + Mio_Library_t* userLib, + double DelayTarget, + double AreaMulti, + double DelayMulti, + float LogFan, + float Slew, + float Gain, + int nGatesMin, + int fRecovery, + int fSwitching, + int fSkipFanout, + int fUseProfile, + int fUseBuffs, + int fVerbose); +extern Aig_Man_t* Abc_NtkToDar(Abc_Ntk_t* pNtk, int fExors, int fRegisters); +extern Aig_Man_t* Abc_NtkToDarChoices(Abc_Ntk_t* pNtk); +extern Gia_Man_t* Gia_ManAigSynch2(Gia_Man_t* p, + void* pPars, + int nLutSize, + int nRelaxRatio); +extern Gia_Man_t* Gia_ManCheckFalse(Gia_Man_t* p, + int nSlackMax, + int nTimeOut, + int fVerbose, + int fVeryVerbose); +extern Vec_Ptr_t* Abc_NtkCollectCiNames(Abc_Ntk_t* pNtk); +extern Vec_Ptr_t* Abc_NtkCollectCoNames(Abc_Ntk_t* pNtk); +extern void Abc_NtkRedirectCiCo(Abc_Ntk_t* pNtk); +extern void Abc_FrameSetLibGen(void* pLib); +} // namespace abc + +namespace rmp { +using utl::RMP; + +static void replaceGia(GiaOp::Type& gia, abc::Gia_Man_t* new_gia) +{ + // Operation does not allocate new gia + if (gia.get() == new_gia) { + return; + } + if (gia->vNamesIn && !new_gia->vNamesIn) { + std::swap(gia->vNamesIn, new_gia->vNamesIn); + } + if (gia->vNamesOut && !new_gia->vNamesOut) { + std::swap(gia->vNamesOut, new_gia->vNamesOut); + } + if (gia->vNamesNode && !new_gia->vNamesNode) { + std::swap(gia->vNamesNode, new_gia->vNamesNode); + } + gia.reset(new_gia); +} + +std::vector GiaOps(utl::Logger* logger) +{ + // GIA ops as lambdas + // All the magic numbers are defaults from abc/src/base/abci/abc.c + // Or from the ORFS abc_speed script + auto step = [logger](const char* msg, auto func) { + return [logger, msg, func](auto& gia) { + debugPrint(logger, RMP, "gia", 1, msg); + replaceGia(gia, func(gia)); + }; + }; + + std::vector all_ops = { + // &st + step("Starting rehash &st", + [](auto& g) { return Gia_ManRehash(g.get(), false); }), + // &dch + [logger](auto& g) { + if (!g->pReprs) { + debugPrint( + logger, RMP, "gia", 1, "Computing choices before equiv reduce"); + abc::Dch_Pars_t pars = {}; + Dch_ManSetDefaultParams(&pars); + replaceGia(g, Gia_ManPerformDch(g.get(), &pars)); + } + debugPrint(logger, RMP, "gia", 1, "Starting equiv reduce"); + replaceGia(g, Gia_ManEquivReduce(g.get(), true, false, false, false)); + }, + // &syn2 + step("Starting syn2", + [](auto& g) { + return Gia_ManAigSyn2( + g.get(), false, true, 0, 20, 0, false, false); + }), + // &syn3 + step("Starting syn3", + [](auto& g) { return Gia_ManAigSyn3(g.get(), false, false); }), + // &syn4 + step("Starting syn4", + [](auto& g) { return Gia_ManAigSyn4(g.get(), false, false); }), + // &retime + step("Starting retime", + [](auto& g) { return Gia_ManRetimeForward(g.get(), 100, false); }), + // &dc2 + step("Starting heavy rewriting", + [](auto& g) { return Gia_ManCompress2(g.get(), true, false); }), + // &b + step("Starting &b", + [](auto& g) { + return Gia_ManAreaBalance( + g.get(), false, ABC_INFINITY, false, false); + }), + // &b -d + step( + "Starting &b - d", + [](auto& g) { return Gia_ManBalance(g.get(), false, false, false); }), + // &false + [logger](auto& gia) { + debugPrint(logger, RMP, "gia", 1, "Starting false path elimination"); + utl::SuppressStdout nostdout(logger); + replaceGia(gia, Gia_ManCheckFalse(gia.get(), 0, 0, false, false)); + }, + // &reduce + [logger](auto& g) { + if (!g->pReprs) { + debugPrint( + logger, RMP, "gia", 1, "Computing choices before equiv reduce"); + abc::Dch_Pars_t pars = {}; + Dch_ManSetDefaultParams(&pars); + replaceGia(g, Gia_ManPerformDch(g.get(), &pars)); + } + debugPrint(logger, RMP, "gia", 1, "Starting equiv reduce and remap"); + replaceGia(g, Gia_ManEquivReduceAndRemap(g.get(), true, false)); + }, + + // &if -g -K 6 + [logger](auto& g) { + if (Gia_ManHasMapping(g.get())) { + debugPrint(logger, + RMP, + "gia", + 1, + "GIA has mapping - rehashing before mapping"); + replaceGia(g, Gia_ManRehash(g.get(), false)); + } + abc::If_Par_t pars = {}; + Gia_ManSetIfParsDefault(&pars); + pars.fDelayOpt = true; + pars.nLutSize = 6; + pars.fTruth = true; + pars.fCutMin = true; + pars.fExpRed = false; + debugPrint(logger, RMP, "gia", 1, "Starting SOP balancing"); + replaceGia(g, Gia_ManPerformMapping(g.get(), &pars)); + }, + + // &synch2 + [logger](auto& g) { + abc::Dch_Pars_t pars = {}; + Dch_ManSetDefaultParams(&pars); + pars.nBTLimit = 100; + debugPrint(logger, RMP, "gia", 1, "Starting synch2"); + replaceGia(g, Gia_ManAigSynch2(g.get(), &pars, 6, 20)); + }}; + /* Some ABC functions/commands that could be used, but crash in some + permutations: + * &nf. Call it like this: + namespace abc { + extern Gia_Man_t* Nf_ManPerformMapping(Gia_Man_t* pGia, + Jf_Par_t* pPars); + } + abc::Jf_Par_t pars = {}; + Nf_ManSetDefaultPars(&pars); + new_gia = Nf_ManPerformMapping(gia, &pars); + It crashes on a null pointer due to a missing time manager. We can make + the time manager: + gia->pManTime = abc::Tim_ManStart(Gia_ManCiNum(new_gia), + Gia_ManCoNum(new_gia)); + But then, an assert deep in &nf fails. + * &dsd. Call it like this: + namespace abc { + extern Gia_Man_t* Gia_ManCollapseTest(Gia_Man_t* p, int fVerbose); + } + new_gia = Gia_ManCollapseTest(gia, false); + An assert fails. + + Some functions/commands don't actually exist: + * &resub + * &reshape, &reshape -a + These are just stubs that return null. + */ + std::vector ops; + ops.reserve(all_ops.size()); + for (size_t i = 0; i < all_ops.size(); ++i) { + ops.emplace_back(i, all_ops[i]); + } + return ops; +} + +static GiaOp::Type initGia(abc::Abc_Ntk_t* ntk, utl::Logger* logger) +{ + debugPrint(logger, RMP, "gia", 1, "Converting to GIA"); + assert(!Abc_NtkIsStrash(ntk)); + // derive comb GIA + auto strash = WrapUnique(Abc_NtkStrash(ntk, false, true, false)); + auto aig = WrapUnique(Abc_NtkToDar(strash.get(), false, false)); + abc::Gia_Man_t* gia = Gia_ManFromAig(aig.get()); + // perform undc/zero + auto inits = Abc_NtkCollectLatchValuesStr(ntk); + { + auto temp = WrapUnique(gia); + gia = Gia_ManDupZeroUndc(gia, inits, 0, false, false); + } + ABC_FREE(inits); + // copy names + gia->vNamesIn = abc::Abc_NtkCollectCiNames(ntk); + gia->vNamesOut = abc::Abc_NtkCollectCoNames(ntk); + return WrapUnique(gia); +} + +void RunGia(sta::dbSta* sta, + const std::vector& candidate_vertices, + cut::AbcLibrary& abc_library, + const std::vector& gia_ops, + size_t resize_iters, + utl::UniqueName& name_generator, + utl::Logger* logger) +{ + sta::dbNetwork* network = sta->getDbNetwork(); + + // Disable incremental timing. + sta->graphDelayCalc()->delaysInvalid(); + sta->search()->arrivalsInvalid(); + sta->search()->endpointsInvalid(); + + cut::LogicExtractorFactory logic_extractor(sta, logger); + for (sta::Vertex* negative_endpoint : candidate_vertices) { + logic_extractor.AppendEndpoint(negative_endpoint); + } + + cut::LogicCut cut = logic_extractor.BuildLogicCut(abc_library); + + utl::UniquePtrWithDeleter mapped_abc_network + = cut.BuildMappedAbcNetwork(abc_library, network, logger); + + utl::UniquePtrWithDeleter current_network( + abc::Abc_NtkToLogic( + const_cast(mapped_abc_network.get())), + &abc::Abc_NtkDelete); + + auto* library + = static_cast(mapped_abc_network->pManFunc); + + // Install library for NtkMap + abc::Abc_FrameSetLibGen(library); + + debugPrint(logger, + RMP, + "gia", + 1, + "Mapped ABC network has {} nodes and {} POs.", + abc::Abc_NtkNodeNum(current_network.get()), + abc::Abc_NtkPoNum(current_network.get())); + + current_network->pManFunc = library; + + { + auto gia = initGia(current_network.get(), logger); + + // Run all the given GIA ops + for (auto& op : gia_ops) { + op.op(gia); + } + debugPrint(logger, RMP, "gia", 1, "Converting GIA to network"); + abc::Extra_UtilGetoptReset(); + + if (Gia_ManHasCellMapping(gia.get())) { + current_network + = WrapUnique(abc::Abc_NtkFromCellMappedGia(gia.get(), false)); + } else if (Gia_ManHasMapping(gia.get()) || gia->pMuxes) { + current_network + = WrapUnique(Abc_NtkFromMappedGia(gia.get(), false, false)); + } else { + if (Gia_ManHasDangling(gia.get()) != 0) { + debugPrint(logger, RMP, "gia", 1, "Rehashing before conversion"); + replaceGia(gia, Gia_ManRehash(gia.get(), false)); + } + assert(Gia_ManHasDangling(gia.get()) == 0); + auto aig = WrapUnique(abc::Gia_ManToAig(gia.get(), false)); + current_network = WrapUnique(Abc_NtkFromAigPhase(aig.get())); + current_network->pName = abc::Extra_UtilStrsav(aig->pName); + } + + assert(gia->vNamesIn); + for (int i = 0; i < abc::Abc_NtkCiNum(current_network.get()); i++) { + assert(i < Vec_PtrSize(gia->vNamesIn)); + abc::Abc_Obj_t* obj = abc::Abc_NtkCi(current_network.get(), i); + assert(obj); + Nm_ManDeleteIdName(current_network->pManName, obj->Id); + Abc_ObjAssignName( + obj, static_cast(Vec_PtrEntry(gia->vNamesIn, i)), nullptr); + } + assert(gia->vNamesOut); + for (int i = 0; i < abc::Abc_NtkCoNum(current_network.get()); i++) { + assert(i < Vec_PtrSize(gia->vNamesOut)); + abc::Abc_Obj_t* obj = Abc_NtkCo(current_network.get(), i); + assert(obj); + Nm_ManDeleteIdName(current_network->pManName, obj->Id); + assert(Abc_ObjIsPo(obj)); + Abc_ObjAssignName( + obj, static_cast(Vec_PtrEntry(gia->vNamesOut, i)), nullptr); + } + + // decouple CI/CO with the same name + if (!Abc_NtkIsStrash(current_network.get()) + && (gia->vNamesIn || gia->vNamesOut)) { + abc::Abc_NtkRedirectCiCo(current_network.get()); + } + } + + if (!Abc_NtkIsStrash(current_network.get())) { + current_network = WrapUnique( + abc::Abc_NtkStrash(current_network.get(), false, true, false)); + } + + { + utl::SuppressStdout nostdout(logger); + current_network = WrapUnique(abc::Abc_NtkMap(current_network.get(), + nullptr, + /*DelayTarget=*/1.0, + /*AreaMulti=*/0.0, + /*DelayMulti=*/2.5, + /*LogFan=*/0.0, + /*Slew=*/0.0, + /*Gain=*/250.0, + /*nGatesMin=*/0, + /*fRecovery=*/true, + /*fSwitching=*/false, + /*fSkipFanout=*/false, + /*fUseProfile=*/false, + /*fUseBuffs=*/false, + /*fVerbose=*/false)); + } + + abc::Abc_NtkCleanup(current_network.get(), /*fVerbose=*/false); + + current_network = WrapUnique(abc::Abc_NtkDupDfs(current_network.get())); + + if (resize_iters > 0) { + // All the magic numbers are defaults from abc/src/base/abci/abc.c + utl::SuppressStdout nostdout(logger); + abc::SC_SizePars pars = {}; + pars.nIters = resize_iters; + pars.nIterNoChange = 50; + pars.Window = 1; + pars.Ratio = 10; + pars.Notches = 1000; + pars.DelayUser = 0; + pars.DelayGap = 0; + pars.TimeOut = 0; + pars.BuffTreeEst = 0; + pars.BypassFreq = 0; + pars.fUseDept = true; + abc::Abc_SclUpsizePerform( + abc_library.abc_library(), current_network.get(), &pars, nullptr); + abc::Abc_SclDnsizePerform( + abc_library.abc_library(), current_network.get(), &pars, nullptr); + } + + current_network = WrapUnique(abc::Abc_NtkToNetlist(current_network.get())); + + cut.InsertMappedAbcNetwork( + current_network.get(), abc_library, network, name_generator, logger); +} +} // namespace rmp diff --git a/src/rmp/src/gia.h b/src/rmp/src/gia.h new file mode 100644 index 0000000000..a5bc3a18b2 --- /dev/null +++ b/src/rmp/src/gia.h @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2025-2025, The OpenROAD Authors + +#pragma once + +#include +#include +#include + +#include "aig/gia/gia.h" +#include "cut/abc_library_factory.h" +#include "utl/unique_name.h" + +namespace sta { +class dbSta; +class Vertex; +} // namespace sta + +namespace utl { +class Logger; +} // namespace utl + +namespace rmp { + +struct GiaOp final +{ + using Type = utl::UniquePtrWithDeleter; + using OpType = std::function; + + size_t id; + OpType op; + bool operator==(const GiaOp& other) const { return id == other.id; } + bool operator!=(const GiaOp& other) const { return !(*this == other); } + + template + friend H AbslHashValue(H h, const GiaOp& gia_op) + { + return H::combine(std::move(h), gia_op.id); + } +}; + +std::vector GiaOps(utl::Logger* logger); + +void RunGia(sta::dbSta* sta, + const std::vector& candidate_vertices, + cut::AbcLibrary& abc_library, + const std::vector& gia_ops, + size_t resize_iters, + utl::UniqueName& name_generator, + utl::Logger* logger); +} // namespace rmp diff --git a/src/rmp/src/rmp.i b/src/rmp/src/rmp.i index 9a4146d2fb..8d408d387c 100644 --- a/src/rmp/src/rmp.i +++ b/src/rmp/src/rmp.i @@ -78,7 +78,55 @@ set_annealing_initial_ops(int set_annealing_initial_ops) getRestructure()->setAnnealingInitialOps(set_annealing_initial_ops); } -void resynth_cmd(Corner* corner) { +void +set_genetic_seed(std::mt19937::result_type genetic_seed) +{ + getRestructure()->setGeneticSeed(genetic_seed); +} + +void +set_genetic_pop_size(int genetic_pop_size) +{ + getRestructure()->setGeneticPopSize(genetic_pop_size); +} + +void + set_genetic_mut_prob(float genetic_mut_prob) +{ + getRestructure()->setGeneticMutProb(genetic_mut_prob); +} + +void +set_genetic_cross_prob(float genetic_cross_prob) +{ + getRestructure()->setGeneticCrossProb(genetic_cross_prob); +} + +void +set_genetic_tourn_size(int genetic_tourn_size) +{ + getRestructure()->setGeneticTournSize(genetic_tourn_size); +} + +void +set_genetic_tourn_prob(float genetic_tourn_prob) +{ + getRestructure()->setGeneticTournProb(genetic_tourn_prob); +} + +void +set_genetic_iters(int genetic_iters) +{ + getRestructure()->setGeneticIters(genetic_iters); +} + +void +set_genetic_initial_ops(int genetic_initial_ops) +{ + getRestructure()->setGeneticInitialOps(genetic_initial_ops); +} + + void resynth_cmd(Corner* corner) { getRestructure()->resynth(corner); } @@ -86,6 +134,10 @@ void resynth_annealing_cmd(Corner* corner) { getRestructure()->resynthAnnealing(corner); } +void resynth_genetic_cmd(Corner* corner) { + getRestructure()->resynthGenetic(corner); +} + void restructure_cmd(char* liberty_file_name, char* target, float slack_threshold, int depth_threshold, char* workdir_name, char* abc_logfile) diff --git a/src/rmp/src/rmp.tcl b/src/rmp/src/rmp.tcl index 281ec4630c..cb0f980f66 100644 --- a/src/rmp/src/rmp.tcl +++ b/src/rmp/src/rmp.tcl @@ -152,3 +152,54 @@ proc resynth_annealing { args } { rmp::resynth_annealing_cmd $corner } + +sta::define_cmd_args "resynth_genetic" { + [-corner corner] + [-slack_threshold slack_threshold] + [-seed seed] + [-pop_size pop_size] + [-mut_prob mut_prob] + [-cross_prob cross_prob] + [-tourn_prob tourn_prob] + [-tourn_size tourn_size] + [-iters iters] + [-initial_ops initial_ops] + } + +proc resynth_genetic { args } { + sta::parse_key_args "resynth_genetic" args \ + keys {-corner -iters -seed -pop_size -mut_prob -cross_prob \ + -tourn_size -tourn_prob -initial_ops -slack_threshold} \ + flags {} + + set corner [sta::parse_corner keys] + if { [info exists keys(-slack_threshold)] } { + rmp::set_slack_threshold $keys(-slack_threshold) + } + if { [info exists keys(-seed)] } { + rmp::set_genetic_seed $keys(-seed) + } + if { [info exists keys(-pop_size)] } { + rmp::set_genetic_pop_size $keys(-pop_size) + } + if { [info exists keys(-mut_prob)] } { + rmp::set_genetic_mut_prob $keys(-mut_prob) + } + if { [info exists keys(-cross_prob)] } { + rmp::set_genetic_cross_prob $keys(-cross_prob) + } + if { [info exists keys(-tourn_size)] } { + rmp::set_genetic_tourn_size $keys(-tourn_size) + } + if { [info exists keys(-tourn_prob)] } { + rmp::set_genetic_tourn_prob $keys(-tourn_prob) + } + if { [info exists keys(-iters)] } { + rmp::set_genetic_iters $keys(-iters) + } + if { [info exists keys(-initial_ops)] } { + rmp::set_genetic_initial_ops $keys(-initial_ops) + } + + rmp::resynth_genetic_cmd $corner +} diff --git a/src/rmp/src/slack_tuning_strategy.cpp b/src/rmp/src/slack_tuning_strategy.cpp new file mode 100644 index 0000000000..c85a4c3892 --- /dev/null +++ b/src/rmp/src/slack_tuning_strategy.cpp @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2025-2025, The OpenROAD Authors + +#include "slack_tuning_strategy.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/random/random.h" +#include "cut/abc_library_factory.h" +#include "db_sta/dbNetwork.hh" +#include "db_sta/dbSta.hh" +#include "gia.h" +#include "odb/db.h" +#include "sta/Delay.hh" +#include "sta/MinMax.hh" +#include "utils.h" +#include "utl/Logger.h" +#include "utl/unique_name.h" + +namespace rmp { + +// The magic numbers are defaults from abc/src/base/abci/abc.c +constexpr size_t SEARCH_RESIZE_ITERS = 100; +constexpr size_t FINAL_RESIZE_ITERS = 1000; + +using utl::RMP; + +std::string SolutionSlack::toString() const +{ + if (solution_.empty()) { + return "[]"; + } + + std::ostringstream resStream; + resStream << '[' << std::to_string(solution_.front().id); + for (int i = 1; i < solution_.size(); i++) { + resStream << ", " << std::to_string(solution_[i].id); + } + resStream << "], worst slack: "; + + if (worst_slack_) { + resStream << *worst_slack_; + } else { + resStream << "not computed"; + } + return resStream.str(); +} + +SolutionSlack::Type SolutionSlack::RandomNeighbor( + const SolutionSlack::Type& all_ops, + utl::Logger* logger, + std::mt19937& random) const +{ + SolutionSlack::Type sol = solution_; + enum class Move : uint8_t + { + ADD, + REMOVE, + SWAP, + COUNT + }; + Move move = Move::ADD; + if (sol.size() > 1) { + const auto count = static_cast>(Move::COUNT); + move = Move(absl::Uniform(random, 0, count)); + } + switch (move) { + case Move::ADD: { + debugPrint(logger, RMP, "slack_tunning", 2, "Adding a new GIA operation"); + size_t i = absl::Uniform(random, 0, sol.size() + 1); + size_t j = absl::Uniform(random, 0, all_ops.size()); + sol.insert(sol.begin() + i, all_ops[j]); + } break; + case Move::REMOVE: { + debugPrint(logger, RMP, "slack_tunning", 2, "Removing a GIA operation"); + size_t i = absl::Uniform(random, 0, sol.size()); + sol.erase(sol.begin() + i); + } break; + case Move::SWAP: { + debugPrint( + logger, RMP, "slack_tunning", 2, "Swapping adjacent GIA operations"); + assert(sol.size() > 1); + size_t i = absl::Uniform(random, 0, sol.size() - 1); + std::swap(sol[i], sol[i + 1]); + } break; + case Move::COUNT: + // TODO replace with std::unreachable() once we reach c++23 + break; + } + return sol; +} + +static std::pair GetWorstSlack(sta::dbSta* sta, + sta::Corner* corner) +{ + sta::Slack worst_slack; + sta::Vertex* worst_vertex = nullptr; + sta->worstSlack(corner, sta::MinMax::max(), worst_slack, worst_vertex); + return {worst_slack, worst_vertex}; +} + +sta::Vertex* SolutionSlack::Evaluate( + const std::vector& candidate_vertices, + cut::AbcLibrary& abc_library, + sta::Corner* corner, + sta::dbSta* sta, + utl::UniqueName& name_generator, + utl::Logger* logger) +{ + auto block = sta->db()->getChip()->getBlock(); + odb::dbDatabase::beginEco(block); + + RunGia(sta, + candidate_vertices, + abc_library, + solution_, + SEARCH_RESIZE_ITERS, + name_generator, + logger); + + odb::dbDatabase::endEco(block); + + auto [worst_slack, worst_vertex] = GetWorstSlack(sta, corner); + worst_slack_ = worst_slack; + + odb::dbDatabase::undoEco(block); + return worst_vertex; +} + +void SlackTuningStrategy::OptimizeDesign(sta::dbSta* sta, + utl::UniqueName& name_generator, + rsz::Resizer* resizer, + utl::Logger* logger) +{ + sta->ensureGraph(); + sta->ensureLevelized(); + sta->searchPreamble(); + sta->ensureClkNetwork(); + + auto candidate_vertices = GetEndpoints(sta, resizer, slack_threshold_); + if (candidate_vertices.empty()) { + logger->info(utl::RMP, + 58, + "All endpoints have slack above threshold, nothing to do."); + return; + } + + logger->info(RMP, + 59, + "Resynthesis: starting tuning algorithm, Worst slack is {}", + GetWorstSlack(sta, corner_).first); + + cut::AbcLibraryFactory factory(logger); + factory.AddDbSta(sta); + factory.AddResizer(resizer); + factory.SetCorner(corner_); + cut::AbcLibrary abc_library = factory.Build(); + + std::vector all_ops = GiaOps(logger); + + const auto& best_ops = RunStrategy(all_ops, + candidate_vertices, + abc_library, + sta, + name_generator, + resizer, + logger); + + logger->info( + RMP, 67, "Resynthesis: End of slack tuning, applying ABC operations"); + + // Apply the ops + RunGia(sta, + candidate_vertices, + abc_library, + best_ops, + FINAL_RESIZE_ITERS, + name_generator, + logger); + logger->info(RMP, + 68, + "Resynthesis: Worst slack is {}", + GetWorstSlack(sta, corner_).first); +} + +} // namespace rmp diff --git a/src/rmp/src/slack_tuning_strategy.h b/src/rmp/src/slack_tuning_strategy.h new file mode 100644 index 0000000000..420b81b482 --- /dev/null +++ b/src/rmp/src/slack_tuning_strategy.h @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2025-2025, The OpenROAD Authors + +#pragma once + +#include +#include +#include +#include + +#include "cut/abc_library_factory.h" +#include "gia.h" +#include "resynthesis_strategy.h" +#include "sta/Delay.hh" +#include "utl/unique_name.h" + +namespace rsz { +class Resizer; +} // namespace rsz + +namespace sta { +class dbSta; +class Corner; +class Vertex; +} // namespace sta + +namespace utl { +class Logger; +} // namespace utl + +namespace rmp { + +struct SolutionSlack final +{ + using Type = std::vector; + Type solution_; + std::optional worst_slack_ = std::nullopt; + + std::string toString() const; + Type RandomNeighbor(const Type& all_ops, + utl::Logger* logger, + std::mt19937& random) const; + + sta::Vertex* Evaluate(const std::vector& candidate_vertices, + cut::AbcLibrary& abc_library, + sta::Corner* corner, + sta::dbSta* sta, + utl::UniqueName& name_generator, + utl::Logger* logger); +}; + +// TODO docs +class SlackTuningStrategy : public ResynthesisStrategy +{ + public: + explicit SlackTuningStrategy(sta::Corner* corner, + sta::Slack slack_threshold, + std::optional seed, + unsigned iterations, + unsigned initial_ops) + : corner_(corner), + slack_threshold_(slack_threshold), + iterations_(iterations), + initial_ops_(initial_ops) + { + if (seed) { + random_.seed(*seed); + } + } + + void OptimizeDesign(sta::dbSta* sta, + utl::UniqueName& name_generator, + rsz::Resizer* resizer, + utl::Logger* logger) override; + + virtual std::vector RunStrategy( + const std::vector& all_ops, + const std::vector& candidate_vertices, + cut::AbcLibrary& abc_library, + sta::dbSta* sta, + utl::UniqueName& name_generator, + rsz::Resizer* resizer, + utl::Logger* logger) + = 0; + + protected: + sta::Corner* corner_; + sta::Slack slack_threshold_; + unsigned iterations_; + unsigned initial_ops_; + std::mt19937 random_; +}; + +} // namespace rmp diff --git a/src/rmp/src/utils.cpp b/src/rmp/src/utils.cpp index 432970014f..8f7b82abbe 100644 --- a/src/rmp/src/utils.cpp +++ b/src/rmp/src/utils.cpp @@ -7,6 +7,8 @@ #include +#include "aig/aig/aig.h" +#include "aig/gia/gia.h" #include "base/abc/abc.h" #include "cut/abc_library_factory.h" #include "cut/logic_cut.h" @@ -23,7 +25,15 @@ namespace rmp { utl::UniquePtrWithDeleter WrapUnique(abc::Abc_Ntk_t* ntk) { - return utl::UniquePtrWithDeleter(ntk, &abc::Abc_NtkDelete); + return {ntk, &abc::Abc_NtkDelete}; +} +utl::UniquePtrWithDeleter WrapUnique(abc::Aig_Man_t* aig) +{ + return {aig, &abc::Aig_ManStop}; +} +utl::UniquePtrWithDeleter WrapUnique(abc::Gia_Man_t* gia) +{ + return {gia, &abc::Gia_ManStop}; } std::vector GetEndpoints(sta::dbSta* sta, diff --git a/src/rmp/src/utils.h b/src/rmp/src/utils.h index 0ba12fb998..849aae1b83 100644 --- a/src/rmp/src/utils.h +++ b/src/rmp/src/utils.h @@ -3,20 +3,28 @@ #pragma once -#include +#include +#include "aig/aig/aig.h" +#include "aig/gia/gia.h" #include "base/abc/abc.h" -#include "db_sta/dbSta.hh" -#include "resynthesis_strategy.h" -#include "rsz/Resizer.hh" -#include "sta/Corner.hh" #include "sta/Delay.hh" -#include "utl/Logger.h" +#include "sta/Graph.hh" #include "utl/deleter.h" +namespace rsz { +class Resizer; +} // namespace rsz + +namespace sta { +class dbSta; +} // namespace sta + namespace rmp { utl::UniquePtrWithDeleter WrapUnique(abc::Abc_Ntk_t* ntk); +utl::UniquePtrWithDeleter WrapUnique(abc::Aig_Man_t* aig); +utl::UniquePtrWithDeleter WrapUnique(abc::Gia_Man_t* gia); std::vector GetEndpoints(sta::dbSta* sta, rsz::Resizer* resizer, diff --git a/src/rmp/test/.gitignore b/src/rmp/test/.gitignore new file mode 100644 index 0000000000..dc4c9bdf44 --- /dev/null +++ b/src/rmp/test/.gitignore @@ -0,0 +1,6 @@ +aes_annealing +aes_annealing.v +gcd_annealing1 +gcd_annealing1.v +gcd_annealing2 +gcd_annealing2.v diff --git a/src/rmp/test/BUILD b/src/rmp/test/BUILD index aaa9f5a180..42b957e25e 100644 --- a/src/rmp/test/BUILD +++ b/src/rmp/test/BUILD @@ -27,6 +27,8 @@ COMPULSORY_TESTS = [ "aes_annealing", "gcd_annealing1", "gcd_annealing2", + "aes_genetic", + "gcd_genetic", ] # Disabled in CMakeLists.txt diff --git a/src/rmp/test/CMakeLists.txt b/src/rmp/test/CMakeLists.txt index 18d51c5ec5..6d1b9402ee 100644 --- a/src/rmp/test/CMakeLists.txt +++ b/src/rmp/test/CMakeLists.txt @@ -20,6 +20,8 @@ or_integration_tests( aes_annealing gcd_annealing1 gcd_annealing2 + aes_genetic + gcd_genetic ) # Skipped diff --git a/src/rmp/test/aes_annealing.ok b/src/rmp/test/aes_annealing.ok index c6517c3ef7..7fe6cca6f5 100644 --- a/src/rmp/test/aes_annealing.ok +++ b/src/rmp/test/aes_annealing.ok @@ -87,33 +87,34 @@ wns max -30.92 tns max -191.30 -- After -- +[INFO RMP-0059] Resynthesis: starting tuning algorithm, Worst slack is 3.7464665e-10 Derived GENLIB library "asap7sc7p5t_AO_RVT_SS_nldm_211120" with 169 gates. [INFO RMP-0052] Resynthesis: starting simulated annealing [INFO RMP-0053] Initial temperature: 9.711085e-10, worst slack: 3.217278e-10 -[INFO RMP-0054] Iteration: 10, temperature: 6.7977596e-10, best worst slack: 3.3161102e-10 -[INFO RMP-0054] Iteration: 20, temperature: 3.5607314e-10, best worst slack: 3.6308723e-10 -[INFO RMP-0054] Iteration: 30, temperature: 3.2370287e-11, best worst slack: 3.6308723e-10 -[INFO RMP-0055] Resynthesis: End of simulated annealing, applying operations -[INFO RMP-0056] Resynthesis: Applying ABC operations -[-96.474, -4.095): *** (15) -[ -4.095, 88.283): *** (13) -[ 88.283, 180.661): ************************* (124) -[180.661, 273.039): ** (8) -[273.039, 365.418): (0) -[365.418, 457.796): * (6) -[457.796, 550.174): ************************************************** (250) -[550.174, 642.552): *** (16) -[642.552, 734.930): ************************** (130) -[734.930, 827.309]: ************************** (129) +[INFO RMP-0054] Iteration: 10, temperature: 6.7977596e-10, best worst slack: 3.3809028e-10 +[INFO RMP-0054] Iteration: 20, temperature: 3.5607314e-10, best worst slack: 3.9108505e-10 +[INFO RMP-0054] Iteration: 30, temperature: 3.2370287e-11, best worst slack: 3.9108505e-10 +[INFO RMP-0067] Resynthesis: End of slack tuning, applying ABC operations +[INFO RMP-0068] Resynthesis: Worst slack is 3.9108505e-10 +[-37.163, 49.284): *** (11) +[ 49.284, 135.731): ************************ (93) +[135.731, 222.179): *************** (56) +[222.179, 308.626): (0) +[308.626, 395.073): (0) +[395.073, 481.520): ************************************************** (190) +[481.520, 567.967): ******************* (74) +[567.967, 654.414): ** (8) +[654.414, 740.862): ********************************** (130) +[740.862, 827.309]: ********************************** (129) Cell type report: Count Area Buffer 990 72.03 - Inverter 585 26.21 + Inverter 554 25.28 Sequential cell 562 163.88 - Multi-Input combinational cell 10172 1054.02 - Total 12309 1316.14 + Multi-Input combinational cell 10115 1050.97 + Total 12221 1312.16 Startpoint: u0/w[0][9]$_DFF_P_ (rising edge-triggered flip-flop clocked by core_clock) -Endpoint: u0/subword[19]$_DFF_P_ +Endpoint: u0/subword[18]$_DFF_P_ (rising edge-triggered flip-flop clocked by core_clock) Path Group: core_clock Path Type: max @@ -124,39 +125,38 @@ Corner: slow 0.00 0.00 clock core_clock (rise edge) 0.00 0.00 clock network delay (ideal) 0.00 0.00 ^ u0/w[0][9]$_DFF_P_/CLK (DFFHQNx1_ASAP7_75t_R) - 84.80 84.80 ^ u0/w[0][9]$_DFF_P_/QN (DFFHQNx1_ASAP7_75t_R) - 56.35 141.15 ^ cut_69476/Y (XOR2xp5_ASAP7_75t_R) - 74.24 215.39 ^ cut_69477/Y (XOR2xp5_ASAP7_75t_R) - 31.14 246.53 v cut_69478/Y (XOR2xp5_ASAP7_75t_R) - 227.84 474.37 ^ cut_69480/Y (AOI21xp33_ASAP7_75t_R) - 165.08 639.45 v cut_69567/Y (INVx1_ASAP7_75t_R) - 83.44 722.89 ^ _23145_/CON (HAxp5_ASAP7_75t_R) - 56.78 779.67 v cut_69512/Y (NAND2xp33_ASAP7_75t_R) - 23.85 803.52 ^ cut_69513/Y (INVx1_ASAP7_75t_R) - 20.96 824.49 v cut_69514/Y (NAND2xp33_ASAP7_75t_R) - 64.16 888.65 ^ cut_69515/Y (NAND2xp33_ASAP7_75t_R) - 38.95 927.60 v cut_69820/Y (NOR2xp33_ASAP7_75t_R) - 38.27 965.87 v cut_69821/Y (AO21x1_ASAP7_75t_R) - 17.31 983.17 ^ cut_69827/Y (NOR2xp33_ASAP7_75t_R) - 20.54 1003.71 v cut_69830/Y (NOR2xp33_ASAP7_75t_R) - 20.10 1023.81 ^ cut_69831/Y (NOR2xp33_ASAP7_75t_R) - 18.94 1042.75 v cut_69832/Y (NOR2xp33_ASAP7_75t_R) - 23.90 1066.65 ^ cut_69865/Y (NOR2xp33_ASAP7_75t_R) - 0.00 1066.65 ^ u0/subword[19]$_DFF_P_/D (DFFHQNx1_ASAP7_75t_R) - 1066.65 data arrival time + 86.37 86.37 v u0/w[0][9]$_DFF_P_/QN (DFFHQNx1_ASAP7_75t_R) + 55.92 142.29 v cut_66958/Y (XNOR2xp5_ASAP7_75t_R) + 63.13 205.41 v cut_66959/Y (XNOR2xp5_ASAP7_75t_R) + 43.42 248.84 v cut_66960/Y (XNOR2xp5_ASAP7_75t_R) + 190.48 439.32 ^ cut_66962/Y (AOI21xp33_ASAP7_75t_R) + 150.43 589.75 v cut_66963/Y (INVx1_ASAP7_75t_R) + 72.55 662.29 ^ _23145_/CON (HAxp5_ASAP7_75t_R) + 74.18 736.47 v cut_66896/Y (NAND2xp33_ASAP7_75t_R) + 54.12 790.59 ^ cut_67164/Y (NOR2xp33_ASAP7_75t_R) + 52.69 843.28 v cut_67165/Y (NOR2xp33_ASAP7_75t_R) + 31.60 874.88 ^ cut_67166/Y (OAI21xp33_ASAP7_75t_R) + 20.48 895.36 v cut_67167/Y (NAND2xp33_ASAP7_75t_R) + 20.52 915.88 ^ cut_67168/Y (NAND2xp33_ASAP7_75t_R) + 16.44 932.33 v cut_67169/Y (NAND2xp33_ASAP7_75t_R) + 28.00 960.33 ^ cut_67191/Y (NAND2xp33_ASAP7_75t_R) + 21.71 982.04 v cut_67192/Y (NOR2xp33_ASAP7_75t_R) + 25.40 1007.44 ^ cut_67237/Y (NOR2xp33_ASAP7_75t_R) + 0.00 1007.44 ^ u0/subword[18]$_DFF_P_/D (DFFHQNx1_ASAP7_75t_R) + 1007.44 data arrival time 1000.00 1000.00 clock core_clock (rise edge) 0.00 1000.00 clock network delay (ideal) 0.00 1000.00 clock reconvergence pessimism - 1000.00 ^ u0/subword[19]$_DFF_P_/CLK (DFFHQNx1_ASAP7_75t_R) - -29.82 970.18 library setup time - 970.18 data required time + 1000.00 ^ u0/subword[18]$_DFF_P_/CLK (DFFHQNx1_ASAP7_75t_R) + -29.72 970.28 library setup time + 970.28 data required time --------------------------------------------------------- - 970.18 data required time - -1066.65 data arrival time + 970.28 data required time + -1007.44 data arrival time --------------------------------------------------------- - -96.47 slack (VIOLATED) + -37.16 slack (VIOLATED) -wns max -96.47 -tns max -686.58 +wns max -37.16 +tns max -145.40 diff --git a/src/rmp/test/aes_genetic.ok b/src/rmp/test/aes_genetic.ok new file mode 100644 index 0000000000..3d4235e9a6 --- /dev/null +++ b/src/rmp/test/aes_genetic.ok @@ -0,0 +1,172 @@ +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13156, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13189, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13222, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13255, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13288, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13321, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13354, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 14748, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 14781, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 14814, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13178, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13211, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13244, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13277, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13310, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13343, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13376, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 14772, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 14805, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 14838, timing group from output port. +[INFO ODB-0227] LEF file: ./asap7/asap7_tech_1x_201209.lef, created 30 layers, 9 vias +[INFO ODB-0227] LEF file: ./asap7/asap7sc7p5t_28_R_1x_220121a.lef, created 212 library cells +[WARNING STA-0441] set_input_delay relative to a clock defined on the same port/pin not allowed. +-- Before -- + +Cell type report: Count Area + Buffer 1081 78.80 + Inverter 458 20.03 + Sequential cell 562 163.88 + Multi-Input combinational cell 9806 1050.62 + Total 11907 1313.34 +[-30.917, 54.906): ***** (21) +[ 54.906, 140.728): ********************** (92) +[140.728, 226.551): *********** (47) +[226.551, 312.373): ************************************************** (212) +[312.373, 398.196): ******* (29) +[398.196, 484.018): **** (19) +[484.018, 569.841): ** (10) +[569.841, 655.664): * (3) +[655.664, 741.486): ****************************** (129) +[741.486, 827.309]: ****************************** (129) +Startpoint: ld (input port clocked by core_clock) +Endpoint: u0/subword[19]$_DFF_P_ + (rising edge-triggered flip-flop clocked by core_clock) +Path Group: core_clock +Path Type: max +Corner: slow + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock core_clock (rise edge) + 0.00 0.00 clock network delay (ideal) + 200.00 200.00 ^ input external delay + 0.00 200.00 ^ ld (in) + 43.55 243.55 ^ _12054_/Y (BUFx2_ASAP7_75t_R) + 61.28 304.83 ^ _12066_/Y (BUFx2_ASAP7_75t_R) + 61.08 365.91 ^ _12067_/Y (BUFx2_ASAP7_75t_R) + 48.16 414.07 ^ _12197_/Y (OA21x2_ASAP7_75t_R) + 65.83 479.90 ^ _12198_/Y (BUFx2_ASAP7_75t_R) + 78.77 558.68 v _13022_/Y (INVx1_ASAP7_75t_R) + 85.51 644.19 ^ _23139_/CON (HAxp5_ASAP7_75t_R) + 39.37 683.56 v _23139_/SN (HAxp5_ASAP7_75t_R) + 56.95 740.51 v _13045_/Y (BUFx2_ASAP7_75t_R) + 53.72 794.23 v _13111_/Y (OA21x2_ASAP7_75t_R) + 46.41 840.64 v _13289_/Y (AO221x1_ASAP7_75t_R) + 52.20 892.84 v _13290_/Y (OA211x2_ASAP7_75t_R) + 42.82 935.66 v _13295_/Y (OR3x1_ASAP7_75t_R) + 52.15 987.81 v _13296_/Y (OA211x2_ASAP7_75t_R) + 33.57 1021.38 v _13297_/Y (AO21x1_ASAP7_75t_R) + 0.00 1021.38 v u0/subword[19]$_DFF_P_/D (DFFHQNx1_ASAP7_75t_R) + 1021.38 data arrival time + +1000.00 1000.00 clock core_clock (rise edge) + 0.00 1000.00 clock network delay (ideal) + 0.00 1000.00 clock reconvergence pessimism + 1000.00 ^ u0/subword[19]$_DFF_P_/CLK (DFFHQNx1_ASAP7_75t_R) + -9.54 990.46 library setup time + 990.46 data required time +--------------------------------------------------------- + 990.46 data required time + -1021.38 data arrival time +--------------------------------------------------------- + -30.92 slack (VIOLATED) + + +wns max -30.92 +tns max -191.30 +-- After -- + +[INFO RMP-0059] Resynthesis: starting tuning algorithm, Worst slack is -3.0917047e-11 +Derived GENLIB library "asap7sc7p5t_AO_RVT_SS_nldm_211120" with 169 gates. +[INFO RMP-0065] Resynthesis: Iteration 0 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 1 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 2 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 3 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 4 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 5 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 6 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 7 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 8 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 9 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 10 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 11 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 12 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 13 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 14 of genetic algorithm +[INFO RMP-0066] Resynthesis: Best result is of individual 0 +[INFO RMP-0067] Resynthesis: End of slack tuning, applying ABC operations +[INFO RMP-0068] Resynthesis: Worst slack is -1.4094392e-11 +[-14.094, 70.046): ***** (18) +[ 70.046, 154.186): **************************** (111) +[154.186, 238.327): ******** (31) +[238.327, 322.467): (0) +[322.467, 406.607): (0) +[406.607, 490.747): ************************************************** (195) +[490.747, 574.888): ******************* (74) +[574.888, 659.028): * (3) +[659.028, 743.168): ********************************* (130) +[743.168, 827.309]: ********************************* (129) +Cell type report: Count Area + Buffer 990 72.03 + Inverter 587 26.51 + Sequential cell 562 163.88 + Multi-Input combinational cell 10166 1052.53 + Total 12305 1314.94 +Startpoint: u0/w[0][1]$_DFF_P_ + (rising edge-triggered flip-flop clocked by core_clock) +Endpoint: u0/subword[10]$_DFF_P_ + (rising edge-triggered flip-flop clocked by core_clock) +Path Group: core_clock +Path Type: max +Corner: slow + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock core_clock (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 ^ u0/w[0][1]$_DFF_P_/CLK (DFFHQNx1_ASAP7_75t_R) + 84.80 84.80 ^ u0/w[0][1]$_DFF_P_/QN (DFFHQNx1_ASAP7_75t_R) + 56.35 141.15 ^ cut_240794/Y (XOR2xp5_ASAP7_75t_R) + 74.24 215.39 ^ cut_240795/Y (XOR2xp5_ASAP7_75t_R) + 47.20 262.59 ^ cut_240796/Y (XOR2xp5_ASAP7_75t_R) + 50.22 312.82 v cut_240798/Y (AOI21xp33_ASAP7_75t_R) + 78.52 391.33 ^ cut_240827/Y (INVx1_ASAP7_75t_R) + 84.22 475.55 v _13443_/Y (INVx1_ASAP7_75t_R) + 130.50 606.06 v _23153_/SN (HAxp5_ASAP7_75t_R) + 84.48 690.54 ^ cut_240865/Y (NOR2xp33_ASAP7_75t_R) + 82.71 773.25 v cut_241124/Y (NOR2xp33_ASAP7_75t_R) + 69.73 842.98 ^ cut_241253/Y (NAND2xp33_ASAP7_75t_R) + 36.61 879.59 ^ _13633_/Y (AO21x1_ASAP7_75t_R) + 37.34 916.93 ^ _13634_/Y (OA211x2_ASAP7_75t_R) + 26.19 943.12 ^ _13635_/Y (AO21x1_ASAP7_75t_R) + 14.01 957.13 v _13652_/Y (AOI21x1_ASAP7_75t_R) + 47.25 1004.38 v _13675_/Y (OA21x2_ASAP7_75t_R) + 0.00 1004.38 v u0/subword[10]$_DFF_P_/D (DFFHQNx1_ASAP7_75t_R) + 1004.38 data arrival time + +1000.00 1000.00 clock core_clock (rise edge) + 0.00 1000.00 clock network delay (ideal) + 0.00 1000.00 clock reconvergence pessimism + 1000.00 ^ u0/subword[10]$_DFF_P_/CLK (DFFHQNx1_ASAP7_75t_R) + -9.72 990.28 library setup time + 990.28 data required time +--------------------------------------------------------- + 990.28 data required time + -1004.38 data arrival time +--------------------------------------------------------- + -14.09 slack (VIOLATED) + + +wns max -14.09 +tns max -47.05 diff --git a/src/rmp/test/aes_genetic.tcl b/src/rmp/test/aes_genetic.tcl new file mode 100644 index 0000000000..e9d126bf11 --- /dev/null +++ b/src/rmp/test/aes_genetic.tcl @@ -0,0 +1,43 @@ +source "helpers.tcl" + +define_corners fast slow +read_liberty -corner slow ./asap7/asap7sc7p5t_AO_RVT_SS_nldm_211120.lib.gz +read_liberty -corner slow ./asap7/asap7sc7p5t_INVBUF_RVT_SS_nldm_220122.lib.gz +read_liberty -corner slow ./asap7/asap7sc7p5t_OA_RVT_SS_nldm_211120.lib.gz +read_liberty -corner slow ./asap7/asap7sc7p5t_SEQ_RVT_SS_nldm_220123.lib +read_liberty -corner slow ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz +read_liberty -corner fast ./asap7/asap7sc7p5t_AO_RVT_FF_nldm_211120.lib.gz +read_liberty -corner fast ./asap7/asap7sc7p5t_INVBUF_RVT_FF_nldm_220122.lib.gz +read_liberty -corner fast ./asap7/asap7sc7p5t_OA_RVT_FF_nldm_211120.lib.gz +read_liberty -corner fast ./asap7/asap7sc7p5t_SEQ_RVT_FF_nldm_220123.lib +read_liberty -corner fast ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz + +read_lef ./asap7/asap7_tech_1x_201209.lef +read_lef ./asap7/asap7sc7p5t_28_R_1x_220121a.lef +read_verilog ./aes_asap7.v +link_design aes +read_sdc ./aes_asap7.sdc + + +puts "-- Before --\n" +report_cell_usage +report_timing_histogram +report_checks +report_wns +report_tns + +puts "-- After --\n" +resynth_genetic \ + -corner slow \ + -initial_ops 5 \ + -iters 15 \ + -pop_size 50 \ + -mut_prob 0.25 \ + -cross_prob 0.25 \ + -tourn_size 9 \ + -tourn_prob 0.8 +report_timing_histogram +report_cell_usage +report_checks +report_wns +report_tns diff --git a/src/rmp/test/gcd_annealing1.ok b/src/rmp/test/gcd_annealing1.ok index 5033fc65d5..c313d6b6e8 100644 --- a/src/rmp/test/gcd_annealing1.ok +++ b/src/rmp/test/gcd_annealing1.ok @@ -95,45 +95,50 @@ wns max -430.88 tns max -15641.01 -- After -- +[INFO RMP-0059] Resynthesis: starting tuning algorithm, Worst slack is 5.5752042e-11 Derived GENLIB library "asap7sc7p5t_AO_RVT_SS_nldm_211120" with 169 gates. [INFO RMP-0052] Resynthesis: starting simulated annealing [INFO RMP-0053] Initial temperature: 4.710931e-10, worst slack: -1.0941836e-10 -[INFO RMP-0054] Iteration: 10, temperature: 4.2869475e-10, best worst slack: -1.021046e-10 [INFO RMP-0057] Reverting to the best found solution -[INFO RMP-0054] Iteration: 20, temperature: 3.8158543e-10, best worst slack: -1.021046e-10 +[INFO RMP-0054] Iteration: 10, temperature: 4.2869475e-10, best worst slack: -1.0941836e-10 [INFO RMP-0057] Reverting to the best found solution -[INFO RMP-0054] Iteration: 30, temperature: 3.3447609e-10, best worst slack: -9.598228e-11 -[INFO RMP-0054] Iteration: 40, temperature: 2.873668e-10, best worst slack: -9.598228e-11 +[INFO RMP-0054] Iteration: 20, temperature: 3.8158543e-10, best worst slack: -1.04245945e-10 [INFO RMP-0057] Reverting to the best found solution -[INFO RMP-0054] Iteration: 50, temperature: 2.4025748e-10, best worst slack: 4.297157e-11 +[INFO RMP-0054] Iteration: 30, temperature: 3.3447609e-10, best worst slack: -1.04245945e-10 [INFO RMP-0057] Reverting to the best found solution -[INFO RMP-0054] Iteration: 60, temperature: 1.9314818e-10, best worst slack: 6.026227e-11 -[INFO RMP-0054] Iteration: 70, temperature: 1.4603886e-10, best worst slack: 1.1420273e-10 +[INFO RMP-0054] Iteration: 40, temperature: 2.873668e-10, best worst slack: -1.04245945e-10 [INFO RMP-0057] Reverting to the best found solution -[INFO RMP-0054] Iteration: 80, temperature: 9.892955e-11, best worst slack: 1.3698773e-10 -[INFO RMP-0054] Iteration: 90, temperature: 5.1820243e-11, best worst slack: 1.448843e-10 +[INFO RMP-0054] Iteration: 50, temperature: 2.4025748e-10, best worst slack: -9.035617e-11 [INFO RMP-0057] Reverting to the best found solution -[INFO RMP-0054] Iteration: 100, temperature: 4.710931e-12, best worst slack: 1.448843e-10 -[INFO RMP-0055] Resynthesis: End of simulated annealing, applying operations -[INFO RMP-0056] Resynthesis: Applying ABC operations -[-151.354, -114.763): ************************************************** (31) -[-114.763, -78.172): ***** (3) -[ -78.172, -41.581): *********** (7) -[ -41.581, -4.990): ***** (3) -[ -4.990, 31.601): ****** (4) -[ 31.601, 68.192): (0) -[ 68.192, 104.783): ***** (3) -[ 104.783, 141.374): (0) -[ 141.374, 177.965): (0) -[ 177.965, 214.556]: *** (2) +[INFO RMP-0054] Iteration: 60, temperature: 1.9314818e-10, best worst slack: -9.035617e-11 +[INFO RMP-0057] Reverting to the best found solution +[INFO RMP-0054] Iteration: 70, temperature: 1.4603886e-10, best worst slack: -9.035617e-11 +[INFO RMP-0057] Reverting to the best found solution +[INFO RMP-0054] Iteration: 80, temperature: 9.892955e-11, best worst slack: -9.035617e-11 +[INFO RMP-0057] Reverting to the best found solution +[INFO RMP-0057] Reverting to the best found solution +[INFO RMP-0054] Iteration: 90, temperature: 5.1820243e-11, best worst slack: -9.035617e-11 +[INFO RMP-0054] Iteration: 100, temperature: 4.710931e-12, best worst slack: -9.035617e-11 +[INFO RMP-0067] Resynthesis: End of slack tuning, applying ABC operations +[INFO RMP-0068] Resynthesis: Worst slack is -9.035617e-11 +[-583.833, -502.603): ************************************************** (34) +[-502.603, -421.373): *** (2) +[-421.373, -340.143): *** (2) +[-340.143, -258.914): *** (2) +[-258.914, -177.684): *** (2) +[-177.684, -96.454): * (1) +[ -96.454, -15.224): *** (2) +[ -15.224, 66.006): ****** (4) +[ 66.006, 147.236): **** (3) +[ 147.236, 228.466]: * (1) Cell type report: Count Area - Inverter 86 5.15 + Inverter 52 2.68 Sequential cell 35 10.21 - Multi-Input combinational cell 343 26.99 - Total 464 42.34 -Startpoint: dpath/a_lt_b$in0[12]$_DFFE_PP_ + Multi-Input combinational cell 284 22.06 + Total 371 34.95 +Startpoint: dpath/a_lt_b$in1[0]$_DFFE_PP_ (rising edge-triggered flip-flop clocked by core_clock) -Endpoint: dpath/a_lt_b$in1[12]$_DFFE_PP_ +Endpoint: dpath/a_lt_b$in1[10]$_DFFE_PP_ (rising edge-triggered flip-flop clocked by core_clock) Path Group: core_clock Path Type: max @@ -143,39 +148,62 @@ Corner: slow --------------------------------------------------------- 0.00 0.00 clock core_clock (rise edge) 0.00 0.00 clock network delay (ideal) - 0.00 0.00 ^ dpath/a_lt_b$in0[12]$_DFFE_PP_/CLK (DFFHQNx1_ASAP7_75t_R) - 65.59 65.59 ^ dpath/a_lt_b$in0[12]$_DFFE_PP_/QN (DFFHQNx1_ASAP7_75t_R) - 19.55 85.13 v cut_63656/Y (INVx1_ASAP7_75t_R) - 201.36 286.50 v _425_/SN (HAxp5_ASAP7_75t_R) - 27.39 313.89 ^ cut_63538/Y (CKINVDCx10_ASAP7_75t_R) - 18.50 332.38 v cut_63539/Y (NAND2x1p5_ASAP7_75t_R) - 22.56 354.95 ^ cut_63540/Y (INVx1_ASAP7_75t_R) - 17.76 372.70 v cut_63541/Y (NAND2x1p5_ASAP7_75t_R) - 19.90 392.61 ^ cut_63545/Y (NOR2x1p5_ASAP7_75t_R) - 20.99 413.59 v cut_63546/Y (NAND2xp5_ASAP7_75t_R) - 26.93 440.52 ^ cut_63547/Y (NAND2x1_ASAP7_75t_R) - 30.34 470.86 v cut_63572/Y (NOR2x1_ASAP7_75t_R) - 32.86 503.72 ^ cut_63573/Y (NAND2x1p5_ASAP7_75t_R) - 21.20 524.92 v cut_63597/Y (NAND2x1p5_ASAP7_75t_R) - 47.73 572.65 ^ cut_63598/Y (NAND2x2_ASAP7_75t_R) - 23.40 596.05 v cut_63659/Y (NAND2xp33_ASAP7_75t_R) - 25.54 621.59 ^ cut_63660/Y (NAND2xp33_ASAP7_75t_R) - 0.00 621.59 ^ dpath/a_lt_b$in1[12]$_DFFE_PP_/D (DFFHQNx1_ASAP7_75t_R) - 621.59 data arrival time + 0.00 0.00 ^ dpath/a_lt_b$in1[0]$_DFFE_PP_/CLK (DFFHQNx1_ASAP7_75t_R) + 65.59 65.59 ^ dpath/a_lt_b$in1[0]$_DFFE_PP_/QN (DFFHQNx1_ASAP7_75t_R) + 25.23 90.82 v cut_59598/Y (INVx1_ASAP7_75t_R) + 53.02 143.84 ^ _421_/CON (HAxp5_ASAP7_75t_R) + 20.86 164.70 v cut_59805/Y (INVx6_ASAP7_75t_R) + 101.30 266.00 ^ _420_/CON (FAx1_ASAP7_75t_R) + 28.86 294.86 v cut_59616/Y (CKINVDCx10_ASAP7_75t_R) + 22.16 317.02 ^ cut_59617/Y (NOR2x2_ASAP7_75t_R) + 21.40 338.42 v cut_59619/Y (NOR2x1p5_ASAP7_75t_R) + 19.37 357.79 ^ cut_59620/Y (NOR2x1p5_ASAP7_75t_R) + 25.28 383.07 v cut_59622/Y (NOR2x1p5_ASAP7_75t_R) + 20.39 403.46 ^ cut_59623/Y (NOR2x1p5_ASAP7_75t_R) + 21.95 425.41 v cut_59625/Y (NOR2x1p5_ASAP7_75t_R) + 19.46 444.87 ^ cut_59626/Y (NOR2x1p5_ASAP7_75t_R) + 25.28 470.15 v cut_59628/Y (NOR2x1p5_ASAP7_75t_R) + 20.39 490.54 ^ cut_59629/Y (NOR2x1p5_ASAP7_75t_R) + 21.95 512.50 v cut_59631/Y (NOR2x1p5_ASAP7_75t_R) + 19.46 531.96 ^ cut_59632/Y (NOR2x1p5_ASAP7_75t_R) + 25.28 557.23 v cut_59634/Y (NOR2x1p5_ASAP7_75t_R) + 20.39 577.63 ^ cut_59635/Y (NOR2x1p5_ASAP7_75t_R) + 21.95 599.58 v cut_59637/Y (NOR2x1p5_ASAP7_75t_R) + 19.46 619.04 ^ cut_59638/Y (NOR2x1p5_ASAP7_75t_R) + 25.28 644.31 v cut_59640/Y (NOR2x1p5_ASAP7_75t_R) + 20.39 664.71 ^ cut_59641/Y (NOR2x1p5_ASAP7_75t_R) + 21.95 686.66 v cut_59643/Y (NOR2x1p5_ASAP7_75t_R) + 19.46 706.12 ^ cut_59644/Y (NOR2x1p5_ASAP7_75t_R) + 25.28 731.40 v cut_59646/Y (NOR2x1p5_ASAP7_75t_R) + 20.39 751.79 ^ cut_59647/Y (NOR2x1p5_ASAP7_75t_R) + 21.95 773.75 v cut_59649/Y (NOR2x1p5_ASAP7_75t_R) + 19.46 793.21 ^ cut_59650/Y (NOR2x1p5_ASAP7_75t_R) + 25.28 818.48 v cut_59652/Y (NOR2x1p5_ASAP7_75t_R) + 20.39 838.88 ^ cut_59653/Y (NOR2x1p5_ASAP7_75t_R) + 21.95 860.83 v cut_59655/Y (NOR2x1p5_ASAP7_75t_R) + 23.66 884.49 ^ cut_59656/Y (NOR2x1p5_ASAP7_75t_R) + 30.25 914.74 v cut_59658/Y (NOR2x1p5_ASAP7_75t_R) + 37.16 951.90 ^ cut_59675/Y (NAND2x1p5_ASAP7_75t_R) + 31.58 983.48 v cut_59740/Y (NOR2xp33_ASAP7_75t_R) + 24.60 1008.08 ^ cut_59741/Y (NOR2xp33_ASAP7_75t_R) + 15.18 1023.26 v cut_59742/Y (NAND2xp5_ASAP7_75t_R) + 30.59 1053.85 ^ cut_59744/Y (NAND2xp33_ASAP7_75t_R) + 0.00 1053.85 ^ dpath/a_lt_b$in1[10]$_DFFE_PP_/D (DFFHQNx1_ASAP7_75t_R) + 1053.85 data arrival time 500.00 500.00 clock core_clock (rise edge) 0.00 500.00 clock network delay (ideal) 0.00 500.00 clock reconvergence pessimism - 500.00 ^ dpath/a_lt_b$in1[12]$_DFFE_PP_/CLK (DFFHQNx1_ASAP7_75t_R) - -29.77 470.23 library setup time - 470.23 data required time + 500.00 ^ dpath/a_lt_b$in1[10]$_DFFE_PP_/CLK (DFFHQNx1_ASAP7_75t_R) + -29.98 470.02 library setup time + 470.02 data required time --------------------------------------------------------- - 470.23 data required time - -621.59 data arrival time + 470.02 data required time + -1053.85 data arrival time --------------------------------------------------------- - -151.35 slack (VIOLATED) + -583.83 slack (VIOLATED) -wns max -151.35 -tns max -5188.85 +wns max -583.83 +tns max -21938.18 Repair timing output passed/skipped equivalence test diff --git a/src/rmp/test/gcd_annealing2.ok b/src/rmp/test/gcd_annealing2.ok index a7626b2d62..ed222df753 100644 --- a/src/rmp/test/gcd_annealing2.ok +++ b/src/rmp/test/gcd_annealing2.ok @@ -95,39 +95,41 @@ wns max -430.88 tns max -15641.01 -- After -- +[INFO RMP-0059] Resynthesis: starting tuning algorithm, Worst slack is 5.5752042e-11 Derived GENLIB library "asap7sc7p5t_AO_RVT_SS_nldm_211120" with 169 gates. [INFO RMP-0052] Resynthesis: starting simulated annealing [INFO RMP-0053] Initial temperature: 1e-10, worst slack: -1.0941836e-10 -[INFO RMP-0054] Iteration: 10, temperature: 9.1000006e-11, best worst slack: -1.02104936e-10 -[INFO RMP-0054] Iteration: 20, temperature: 8.1e-11, best worst slack: 8.012241e-11 -[INFO RMP-0054] Iteration: 30, temperature: 7.1e-11, best worst slack: 1.09160875e-10 -[INFO RMP-0054] Iteration: 40, temperature: 6.1000004e-11, best worst slack: 1.09160875e-10 -[INFO RMP-0054] Iteration: 50, temperature: 5.1e-11, best worst slack: 1.6228e-10 -[INFO RMP-0054] Iteration: 60, temperature: 4.1e-11, best worst slack: 1.6228e-10 -[INFO RMP-0054] Iteration: 70, temperature: 3.1e-11, best worst slack: 1.6228e-10 -[INFO RMP-0054] Iteration: 80, temperature: 2.1e-11, best worst slack: 1.6228e-10 -[INFO RMP-0054] Iteration: 90, temperature: 1.1e-11, best worst slack: 1.6228e-10 -[INFO RMP-0054] Iteration: 100, temperature: 1e-12, best worst slack: 1.6228e-10 -[INFO RMP-0055] Resynthesis: End of simulated annealing, applying operations -[INFO RMP-0056] Resynthesis: Applying ABC operations -[-47.697, -16.477): ************************************************** (37) -[-16.477, 14.742): ******* (5) -[ 14.742, 45.962): ***** (4) -[ 45.962, 77.181): * (1) -[ 77.181, 108.401): *** (2) -[108.401, 139.620): (0) -[139.620, 170.839): *** (2) -[170.839, 202.059): * (1) -[202.059, 233.278): (0) -[233.278, 264.498]: * (1) +[INFO RMP-0054] Iteration: 10, temperature: 9.1000006e-11, best worst slack: 2.3165053e-11 +[INFO RMP-0054] Iteration: 20, temperature: 8.1e-11, best worst slack: 2.3165053e-11 +[INFO RMP-0054] Iteration: 30, temperature: 7.1e-11, best worst slack: 2.3165053e-11 +[INFO RMP-0054] Iteration: 40, temperature: 6.1000004e-11, best worst slack: 2.7621544e-11 +[INFO RMP-0054] Iteration: 50, temperature: 5.1e-11, best worst slack: 3.830361e-11 +[INFO RMP-0054] Iteration: 60, temperature: 4.1e-11, best worst slack: 3.830361e-11 +[INFO RMP-0054] Iteration: 70, temperature: 3.1e-11, best worst slack: 1.03385134e-10 +[INFO RMP-0054] Iteration: 80, temperature: 2.1e-11, best worst slack: 1.03385134e-10 +[INFO RMP-0054] Iteration: 90, temperature: 1.1e-11, best worst slack: 1.03385134e-10 +[INFO RMP-0054] Iteration: 100, temperature: 1e-12, best worst slack: 1.03385134e-10 +[INFO RMP-0067] Resynthesis: End of slack tuning, applying ABC operations +[INFO RMP-0068] Resynthesis: Worst slack is 1.03909215e-10 +[-241.476, -194.181): ************************************************** (32) +[-194.181, -146.886): ***** (3) +[-146.886, -99.591): ****** (4) +[ -99.591, -52.296): *** (2) +[ -52.296, -5.001): *** (2) +[ -5.001, 42.295): ***** (3) +[ 42.295, 89.590): ******** (5) +[ 89.590, 136.885): (0) +[ 136.885, 184.180): (0) +[ 184.180, 231.475]: *** (2) Cell type report: Count Area - Inverter 62 3.11 + Inverter 64 3.73 Sequential cell 35 10.21 - Multi-Input combinational cell 385 28.17 - Total 482 41.48 -Startpoint: dpath/a_lt_b$in0[8]$_DFFE_PP_ + Multi-Input combinational cell 302 24.20 + Total 401 38.14 +Startpoint: dpath/a_lt_b$in1[0]$_DFFE_PP_ (rising edge-triggered flip-flop clocked by core_clock) -Endpoint: resp_msg[15] (output port clocked by core_clock) +Endpoint: dpath/a_lt_b$in0[1]$_DFFE_PP_ + (rising edge-triggered flip-flop clocked by core_clock) Path Group: core_clock Path Type: max Corner: slow @@ -136,34 +138,46 @@ Corner: slow --------------------------------------------------------- 0.00 0.00 clock core_clock (rise edge) 0.00 0.00 clock network delay (ideal) - 0.00 0.00 ^ dpath/a_lt_b$in0[8]$_DFFE_PP_/CLK (DFFHQNx1_ASAP7_75t_R) - 73.77 73.77 v dpath/a_lt_b$in0[8]$_DFFE_PP_/QN (DFFHQNx1_ASAP7_75t_R) - 20.38 94.15 ^ cut_76928/Y (INVx1_ASAP7_75t_R) - 75.10 169.25 ^ _429_/SN (HAxp5_ASAP7_75t_R) - 49.22 218.47 ^ cut_76540/Y (OR2x2_ASAP7_75t_R) - 20.78 239.25 v cut_76807/Y (NOR2xp33_ASAP7_75t_R) - 39.22 278.46 v cut_76808/Y (OR2x2_ASAP7_75t_R) - 35.69 314.16 v cut_76832/Y (OR2x2_ASAP7_75t_R) - 33.21 347.37 v cut_76909/Y (OR2x2_ASAP7_75t_R) - 17.13 364.50 ^ cut_76910/Y (NOR2xp33_ASAP7_75t_R) - 27.19 391.69 v cut_76911/Y (NOR2xp33_ASAP7_75t_R) - 39.00 430.68 v cut_76914/Y (OR2x2_ASAP7_75t_R) - 17.01 447.70 ^ cut_76915/Y (NAND2xp33_ASAP7_75t_R) - 0.00 447.70 ^ resp_msg[15] (out) - 447.70 data arrival time + 0.00 0.00 ^ dpath/a_lt_b$in1[0]$_DFFE_PP_/CLK (DFFHQNx1_ASAP7_75t_R) + 69.08 69.08 ^ dpath/a_lt_b$in1[0]$_DFFE_PP_/QN (DFFHQNx1_ASAP7_75t_R) + 21.96 91.04 v cut_60829/Y (INVx1_ASAP7_75t_R) + 50.30 141.34 ^ _421_/CON (HAxp5_ASAP7_75t_R) + 22.40 163.74 v cut_61010/Y (INVx6_ASAP7_75t_R) + 109.21 272.95 ^ _420_/CON (FAx1_ASAP7_75t_R) + 29.71 302.67 v cut_60867/Y (CKINVDCx10_ASAP7_75t_R) + 22.97 325.64 ^ cut_60868/Y (NOR2x2_ASAP7_75t_R) + 20.60 346.24 v cut_60869/Y (NOR2x1p5_ASAP7_75t_R) + 23.21 369.45 ^ cut_60870/Y (NOR2x1p5_ASAP7_75t_R) + 19.10 388.56 v cut_60871/Y (NOR2x1p5_ASAP7_75t_R) + 18.53 407.09 ^ cut_60872/Y (NOR2x1p5_ASAP7_75t_R) + 32.19 439.28 ^ cut_60873/Y (AND2x4_ASAP7_75t_R) + 15.96 455.24 v cut_60874/Y (NOR2x2_ASAP7_75t_R) + 24.05 479.29 ^ cut_60875/Y (NOR2x2_ASAP7_75t_R) + 19.26 498.55 v cut_60876/Y (NAND2x1p5_ASAP7_75t_R) + 21.85 520.41 ^ cut_60877/Y (NAND2x1p5_ASAP7_75t_R) + 29.65 550.05 v cut_60878/Y (NOR2x2_ASAP7_75t_R) + 45.63 595.68 v cut_60900/Y (OR2x6_ASAP7_75t_R) + 32.78 628.46 ^ cut_60979/Y (NOR2x2_ASAP7_75t_R) + 18.80 647.26 v cut_60991/Y (INVx2_ASAP7_75t_R) + 19.05 666.31 ^ cut_60992/Y (NOR2xp33_ASAP7_75t_R) + 22.18 688.48 v cut_60993/Y (NOR2xp33_ASAP7_75t_R) + 23.20 711.68 ^ cut_60995/Y (NOR2xp33_ASAP7_75t_R) + 0.00 711.68 ^ dpath/a_lt_b$in0[1]$_DFFE_PP_/D (DFFHQNx1_ASAP7_75t_R) + 711.68 data arrival time 500.00 500.00 clock core_clock (rise edge) 0.00 500.00 clock network delay (ideal) 0.00 500.00 clock reconvergence pessimism --100.00 400.00 output external delay - 400.00 data required time + 500.00 ^ dpath/a_lt_b$in0[1]$_DFFE_PP_/CLK (DFFHQNx1_ASAP7_75t_R) + -29.79 470.21 library setup time + 470.21 data required time --------------------------------------------------------- - 400.00 data required time - -447.70 data arrival time + 470.21 data required time + -711.68 data arrival time --------------------------------------------------------- - -47.70 slack (VIOLATED) + -241.48 slack (VIOLATED) -wns max -47.70 -tns max -1112.78 +wns max -241.48 +tns max -8460.52 Repair timing output passed/skipped equivalence test diff --git a/src/rmp/test/gcd_genetic.ok b/src/rmp/test/gcd_genetic.ok new file mode 100644 index 0000000000..c62ed33688 --- /dev/null +++ b/src/rmp/test/gcd_genetic.ok @@ -0,0 +1,181 @@ +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13156, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13189, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13222, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13255, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13288, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13321, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 13354, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 14748, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 14781, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz line 14814, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13178, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13211, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13244, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13277, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13310, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13343, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 13376, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 14772, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 14805, timing group from output port. +[WARNING STA-1212] ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz line 14838, timing group from output port. +[INFO ODB-0227] LEF file: ./asap7/asap7_tech_1x_201209.lef, created 30 layers, 9 vias +[INFO ODB-0227] LEF file: ./asap7/asap7sc7p5t_28_R_1x_220121a.lef, created 212 library cells +[WARNING STA-0441] set_input_delay relative to a clock defined on the same port/pin not allowed. +-- Before -- + +Cell type report: Count Area + Buffer 13 0.95 + Inverter 40 1.75 + Sequential cell 35 10.21 + Multi-Input combinational cell 157 18.76 + Total 245 31.67 +[-430.882, -361.927): ************************************************** (34) +[-361.927, -292.972): * (1) +[-292.972, -224.018): **** (3) +[-224.018, -155.063): *** (2) +[-155.063, -86.108): *** (2) +[ -86.108, -17.153): * (1) +[ -17.153, 51.802): *** (2) +[ 51.802, 120.756): * (1) +[ 120.756, 189.711): ****** (4) +[ 189.711, 258.666]: **** (3) +Startpoint: dpath/a_lt_b$in1[0]$_DFFE_PP_ + (rising edge-triggered flip-flop clocked by core_clock) +Endpoint: dpath/a_lt_b$in1[1]$_DFFE_PP_ + (rising edge-triggered flip-flop clocked by core_clock) +Path Group: core_clock +Path Type: max +Corner: slow + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock core_clock (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 ^ dpath/a_lt_b$in1[0]$_DFFE_PP_/CLK (DFFHQNx1_ASAP7_75t_R) + 71.18 71.18 ^ dpath/a_lt_b$in1[0]$_DFFE_PP_/QN (DFFHQNx1_ASAP7_75t_R) + 23.62 94.80 v _228_/Y (INVx1_ASAP7_75t_R) + 25.22 120.02 ^ _421_/CON (HAxp5_ASAP7_75t_R) + 26.50 146.52 v _341_/Y (INVx1_ASAP7_75t_R) + 45.61 192.13 ^ _420_/CON (FAx1_ASAP7_75t_R) + 21.71 213.84 v _234_/Y (INVx1_ASAP7_75t_R) + 37.93 251.76 v _235_/Y (OA21x2_ASAP7_75t_R) + 38.67 290.43 v _236_/Y (OA21x2_ASAP7_75t_R) + 36.56 326.99 v _237_/Y (OA21x2_ASAP7_75t_R) + 38.65 365.64 v _238_/Y (OA21x2_ASAP7_75t_R) + 36.56 402.21 v _239_/Y (OA21x2_ASAP7_75t_R) + 38.65 440.86 v _240_/Y (OA21x2_ASAP7_75t_R) + 36.56 477.42 v _241_/Y (OA21x2_ASAP7_75t_R) + 38.65 516.07 v _242_/Y (OA21x2_ASAP7_75t_R) + 36.56 552.64 v _243_/Y (OA21x2_ASAP7_75t_R) + 38.65 591.29 v _244_/Y (OA21x2_ASAP7_75t_R) + 36.56 627.85 v _245_/Y (OA21x2_ASAP7_75t_R) + 38.65 666.50 v _246_/Y (OA21x2_ASAP7_75t_R) + 39.54 706.05 v _247_/Y (OA21x2_ASAP7_75t_R) + 44.66 750.70 ^ _248_/Y (OAI21x1_ASAP7_75t_R) + 59.57 810.27 ^ _280_/Y (OA21x2_ASAP7_75t_R) + 47.28 857.56 ^ _281_/Y (BUFx2_ASAP7_75t_R) + 44.40 901.96 ^ _289_/Y (AO222x2_ASAP7_75t_R) + 0.00 901.96 ^ dpath/a_lt_b$in1[1]$_DFFE_PP_/D (DFFHQNx1_ASAP7_75t_R) + 901.96 data arrival time + + 500.00 500.00 clock core_clock (rise edge) + 0.00 500.00 clock network delay (ideal) + 0.00 500.00 clock reconvergence pessimism + 500.00 ^ dpath/a_lt_b$in1[1]$_DFFE_PP_/CLK (DFFHQNx1_ASAP7_75t_R) + -28.92 471.08 library setup time + 471.08 data required time +--------------------------------------------------------- + 471.08 data required time + -901.96 data arrival time +--------------------------------------------------------- + -430.88 slack (VIOLATED) + + +wns max -430.88 +tns max -15641.01 +-- After -- + +[INFO RMP-0059] Resynthesis: starting tuning algorithm, Worst slack is -4.3088177e-10 +Derived GENLIB library "asap7sc7p5t_AO_RVT_SS_nldm_211120" with 169 gates. +[INFO RMP-0065] Resynthesis: Iteration 0 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 1 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 2 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 3 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 4 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 5 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 6 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 7 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 8 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 9 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 10 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 11 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 12 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 13 of genetic algorithm +[INFO RMP-0065] Resynthesis: Iteration 14 of genetic algorithm +[INFO RMP-0066] Resynthesis: Best result is of individual 0 +[INFO RMP-0067] Resynthesis: End of slack tuning, applying ABC operations +[INFO RMP-0068] Resynthesis: Worst slack is -7.6960105e-11 +[-76.960, -43.477): ************************************************** (37) +[-43.477, -9.993): ***** (4) +[ -9.993, 23.490): **** (3) +[ 23.490, 56.974): *** (2) +[ 56.974, 90.457): * (1) +[ 90.457, 123.941): **** (3) +[123.941, 157.424): * (1) +[157.424, 190.908): (0) +[190.908, 224.391): * (1) +[224.391, 257.875]: * (1) +Cell type report: Count Area + Inverter 69 3.57 + Sequential cell 35 10.21 + Multi-Input combinational cell 409 29.28 + Total 513 43.05 +Startpoint: dpath/a_lt_b$in1[0]$_DFFE_PP_ + (rising edge-triggered flip-flop clocked by core_clock) +Endpoint: ctrl/state/out[1]$_DFF_P_ + (rising edge-triggered flip-flop clocked by core_clock) +Path Group: core_clock +Path Type: max +Corner: slow + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock core_clock (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 ^ dpath/a_lt_b$in1[0]$_DFFE_PP_/CLK (DFFHQNx1_ASAP7_75t_R) + 75.75 75.75 ^ dpath/a_lt_b$in1[0]$_DFFE_PP_/QN (DFFHQNx1_ASAP7_75t_R) + 22.03 97.78 v cut_236752/Y (INVx1_ASAP7_75t_R) + 24.08 121.86 ^ _421_/CON (HAxp5_ASAP7_75t_R) + 29.34 151.20 v cut_236789/Y (INVx1_ASAP7_75t_R) + 87.01 238.21 ^ _420_/CON (FAx1_ASAP7_75t_R) + 22.83 261.04 v cut_236577/Y (INVx8_ASAP7_75t_R) + 20.94 281.97 ^ cut_236578/Y (NOR2x1p5_ASAP7_75t_R) + 19.55 301.52 v cut_236579/Y (NOR2xp67_ASAP7_75t_R) + 39.99 341.51 v cut_236580/Y (OR2x2_ASAP7_75t_R) + 17.15 358.66 ^ cut_236581/Y (NAND2x1p5_ASAP7_75t_R) + 22.59 381.25 v cut_236582/Y (NAND2x1_ASAP7_75t_R) + 22.81 404.06 ^ cut_236583/Y (NAND2x1p5_ASAP7_75t_R) + 31.34 435.40 v cut_236584/Y (NAND2x2_ASAP7_75t_R) + 31.43 466.84 ^ cut_236585/Y (NOR2x1p5_ASAP7_75t_R) + 28.04 494.88 v cut_236587/Y (NOR2x1_ASAP7_75t_R) + 37.38 532.26 v cut_236588/Y (OR2x2_ASAP7_75t_R) + 14.73 546.99 ^ cut_236589/Y (NAND2xp5_ASAP7_75t_R) + 0.00 546.99 ^ ctrl/state/out[1]$_DFF_P_/D (DFFHQNx1_ASAP7_75t_R) + 546.99 data arrival time + + 500.00 500.00 clock core_clock (rise edge) + 0.00 500.00 clock network delay (ideal) + 0.00 500.00 clock reconvergence pessimism + 500.00 ^ ctrl/state/out[1]$_DFF_P_/CLK (DFFHQNx1_ASAP7_75t_R) + -29.97 470.03 library setup time + 470.03 data required time +--------------------------------------------------------- + 470.03 data required time + -546.99 data arrival time +--------------------------------------------------------- + -76.96 slack (VIOLATED) + + +wns max -76.96 +tns max -2559.69 +Repair timing output passed/skipped equivalence test diff --git a/src/rmp/test/gcd_genetic.tcl b/src/rmp/test/gcd_genetic.tcl new file mode 100644 index 0000000000..982e761a50 --- /dev/null +++ b/src/rmp/test/gcd_genetic.tcl @@ -0,0 +1,62 @@ +source "helpers.tcl" + +set test_name gcd_genetic + +define_corners fast slow +set lib_files_slow {\ + ./asap7/asap7sc7p5t_AO_RVT_SS_nldm_211120.lib.gz \ + ./asap7/asap7sc7p5t_INVBUF_RVT_SS_nldm_220122.lib.gz \ + ./asap7/asap7sc7p5t_OA_RVT_SS_nldm_211120.lib.gz \ + ./asap7/asap7sc7p5t_SEQ_RVT_SS_nldm_220123.lib \ + ./asap7/asap7sc7p5t_SIMPLE_RVT_SS_nldm_211120.lib.gz\ +} +set lib_files_fast {\ + ./asap7/asap7sc7p5t_AO_RVT_FF_nldm_211120.lib.gz \ + ./asap7/asap7sc7p5t_INVBUF_RVT_FF_nldm_220122.lib.gz \ + ./asap7/asap7sc7p5t_OA_RVT_FF_nldm_211120.lib.gz \ + ./asap7/asap7sc7p5t_SEQ_RVT_FF_nldm_220123.lib \ + ./asap7/asap7sc7p5t_SIMPLE_RVT_FF_nldm_211120.lib.gz\ +} + +foreach lib_file $lib_files_slow { + read_liberty -corner slow $lib_file +} +foreach lib_file $lib_files_fast { + read_liberty -corner fast $lib_file +} + +read_lef ./asap7/asap7_tech_1x_201209.lef +read_lef ./asap7/asap7sc7p5t_28_R_1x_220121a.lef +read_verilog ./gcd_asap7.v +link_design gcd +read_sdc ./gcd_asap7.sdc + + +puts "-- Before --\n" +report_cell_usage +report_timing_histogram +report_checks +report_wns +report_tns +write_verilog_for_eqy $test_name before "None" + +puts "-- After --\n" +resynth_genetic \ + -corner slow \ + -initial_ops 5 \ + -iters 15 \ + -pop_size 100 \ + -mut_prob 0.25 \ + -cross_prob 0.75 \ + -tourn_size 9 \ + -tourn_prob 0.9 +report_timing_histogram +report_cell_usage +report_checks +report_wns +report_tns + +set liberty_files [concat $lib_files_slow $lib_files_fast] +run_equivalence_test $test_name \ + -liberty_files $liberty_files \ + -remove_cells "None"