Skip to content

Commit

Permalink
Merge pull request #6477 from QuantamHD/remapper5
Browse files Browse the repository at this point in the history
rmp: Adds DelayOptimization pass to remapper
  • Loading branch information
maliberty authored Jan 7, 2025
2 parents 210dc45 + 135f05d commit 0346f68
Show file tree
Hide file tree
Showing 10 changed files with 275 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/rmp/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ add_library(rmp_abc_library
abc_library_factory.cpp
logic_extractor.cpp
logic_cut.cpp
delay_optimization_strategy.cpp
)

target_include_directories(rmp_abc_library
Expand Down
2 changes: 2 additions & 0 deletions src/rmp/src/abc_library_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,8 @@ AbcLibrary AbcLibraryFactory::Build()
PopulateAbcSclLibFromSta(abc_library, library);
}
abc::Abc_SclLibNormalize(abc_library);
abc::Abc_SclHashCells(abc_library);
abc::Abc_SclLinkCells(abc_library);

return AbcLibrary(utl::UniquePtrWithDeleter<abc::SC_Lib>(
abc_library, [](abc::SC_Lib* lib) { abc::Abc_SclLibFree(lib); }));
Expand Down
132 changes: 132 additions & 0 deletions src/rmp/src/delay_optimization_strategy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Copyright 2024 Google LLC
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#include "delay_optimization_strategy.h"

#include "abc_library_factory.h"
#include "base/abc/abc.h"
#include "map/mio/mio.h"
#include "map/scl/sclLib.h"
#include "map/scl/sclSize.h"
#include "utl/deleter.h"

namespace abc {
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 void Abc_FrameSetLibGen(void* pLib);
} // namespace abc

namespace rmp {

utl::UniquePtrWithDeleter<abc::Abc_Ntk_t> WrapUnique(abc::Abc_Ntk_t* ntk)
{
return utl::UniquePtrWithDeleter<abc::Abc_Ntk_t>(ntk, &abc::Abc_NtkDelete);
}

void AbcPrintStats(const abc::Abc_Ntk_t* ntk)
{
abc::Abc_NtkPrintStats(const_cast<abc::Abc_Ntk_t*>(ntk),
/*fFactored=*/false,
/*fSaveBest=*/false,
/*fDumpResult=*/false,
/*fUseLutLib=*/false,
/*fPrintMuxes=*/false,
/*fPower=*/false,
/*fGlitch=*/false,
/*fSkipBuf=*/false,
/*fSkipSmall=*/false,
/*fPrintMem=*/false);
}

utl::UniquePtrWithDeleter<abc::Abc_Ntk_t> BufferNetwork(
abc::Abc_Ntk_t* ntk,
AbcLibrary& abc_sc_library)
{
abc::SC_BusPars buffer_parameters;
memset(&buffer_parameters, 0, sizeof(abc::SC_BusPars));
buffer_parameters.GainRatio = 300;
buffer_parameters.Slew
= abc::Abc_SclComputeAverageSlew(abc_sc_library.abc_library());
buffer_parameters.nDegree = 5;
buffer_parameters.fSizeOnly = 0;
buffer_parameters.fAddBufs = false;
buffer_parameters.fBufPis = true;
buffer_parameters.fUseWireLoads = 0;
buffer_parameters.fVerbose = true;
buffer_parameters.fVeryVerbose = false;

utl::UniquePtrWithDeleter<abc::Abc_Ntk_t> buffered_network(
abc::Abc_SclBufferingPerform(
ntk, abc_sc_library.abc_library(), &buffer_parameters),
&abc::Abc_NtkDelete);
return buffered_network;
}

utl::UniquePtrWithDeleter<abc::Abc_Ntk_t> DelayOptimizationStrategy::Optimize(
const abc::Abc_Ntk_t* ntk,
utl::Logger* logger)
{
auto library = static_cast<abc::Mio_Library_t*>(ntk->pManFunc);
// Install library for NtkMap
abc::Abc_FrameSetLibGen(library);

// Set up libraries for buffering
AbcLibraryFactory library_factory(logger);
library_factory.AddDbSta(sta_);
AbcLibrary abc_sc_library = library_factory.Build();

AbcPrintStats(ntk);

utl::UniquePtrWithDeleter<abc::Abc_Ntk_t> current_network(
abc::Abc_NtkToLogic(const_cast<abc::Abc_Ntk_t*>(ntk)),
&abc::Abc_NtkDelete);

current_network = WrapUnique(abc::Abc_NtkStrash(current_network.get(),
/*fAllNodes=*/false,
/*fCleanup=*/true,
/*fRecord=*/false));
current_network = WrapUnique(Abc_NtkBalance(current_network.get(),
/*fDuplicate=*/true,
/*fSelective=*/false,
/*fUpdateLevel=*/true));

current_network = WrapUnique(abc::Abc_NtkMap(current_network.get(),
nullptr,
/*DelayTarget=*/-1.0,
/*AreaMulti=*/0.0,
/*DelayMulti=*/6.0,
/*LogFan=*/10.0,
/*Slew=*/0.0,
/*Gain=*/250.0,
/*nGatesMin=*/0,
/*fRecovery=*/false,
/*fSwitching=*/false,
/*fSkipFanout=*/false,
/*fUseProfile=*/false,
/*fUseBuffs=*/true,
/*fVerbose=*/true));

current_network = BufferNetwork(current_network.get(), abc_sc_library);

current_network = WrapUnique(abc::Abc_NtkToNetlist(current_network.get()));

return current_network;
}

} // namespace rmp
32 changes: 32 additions & 0 deletions src/rmp/src/delay_optimization_strategy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2024 Google LLC
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#pragma once

#include "base/abc/abc.h"
#include "db_sta/dbSta.hh"
#include "logic_optimization_strategy.h"
#include "utl/Logger.h"
#include "utl/deleter.h"

namespace rmp {

class DelayOptimizationStrategy : public LogicOptimizationStrategy
{
public:
~DelayOptimizationStrategy() override = default;

DelayOptimizationStrategy(sta::dbSta* sta) : sta_(sta) {}

utl::UniquePtrWithDeleter<abc::Abc_Ntk_t> Optimize(
const abc::Abc_Ntk_t* ntk,
utl::Logger* logger) override;

private:
sta::dbSta* sta_;
};

} // namespace rmp
2 changes: 1 addition & 1 deletion src/rmp/src/logic_extractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class LogicExtractorFactory
LogicCut BuildLogicCut(AbcLibrary& abc_network);

private:
// Process vertificies from BFS STA output to find the primary inputs.
// Process vertices from BFS STA output to find the primary inputs.
std::vector<sta::Pin*> GetPrimaryInputs(
std::vector<sta::Vertex*>& cut_vertices);
std::vector<sta::Pin*> GetPrimaryOutputs(
Expand Down
54 changes: 54 additions & 0 deletions src/rmp/src/logic_optimization_strategy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2024 Google LLC
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#pragma once

#include "base/abc/abc.h"
#include "db_sta/dbSta.hh"
#include "utl/Logger.h"
#include "utl/deleter.h"

namespace rmp {

// The `LogicOptimizationStrategy` class defines an interface for different
// logic optimization strategies that can be applied to an ABC network.
//
// It provides a virtual `Optimize` method that takes an ABC network and a
// logger as input and returns an optimized version of the network. Concrete
// implementations of this class will implement specific optimization algorithms
// such as delay optimization, area optimization, or a combination of both.
class LogicOptimizationStrategy
{
public:
virtual ~LogicOptimizationStrategy() = default;

// Optimize the given ABC network.
//
// This function takes an ABC network (`abc::Abc_Ntk_t`) and optimizes it
// using a specific logic optimization strategy. The optimized network is
// returned as a `utl::UniquePtrWithDeleter<abc::Abc_Ntk_t>`.
//
// **Important:** This function **does not modify the input network** (`ntk`).
//
// Args:
// ntk: A pointer to the ABC network to be optimized. The network should
// be a technology-mapped network (i.e., a netlist of standard cells).
// logger: A pointer to the logger for reporting messages.
//
// Returns:
// A unique pointer (`utl::UniquePtrWithDeleter`) to the optimized ABC
// network. The deleter ensures that `abc::Abc_NtkDelete` is called when
// the network is no longer needed.
//
// The function is expected to perform the following actions:
// 1. Apply logic optimization techniques (e.g., technology mapping,
// buffering, area/delay optimization) to the copy.
// 2. Return a new network that is optimized according to the strategy.
virtual utl::UniquePtrWithDeleter<abc::Abc_Ntk_t>
Optimize(const abc::Abc_Ntk_t* ntk, utl::Logger* logger) = 0;
};

} // namespace rmp
3 changes: 3 additions & 0 deletions src/rmp/test/aes_nangate45.sdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
create_clock [get_ports clk] -name core_clock -period 0.5
set_input_delay 0.1 [all_inputs] -clock core_clock
set_output_delay 0.1 [all_outputs] -clock core_clock
8 changes: 8 additions & 0 deletions src/rmp/test/aes_nangate45.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# For debugging optimizations

read_liberty src/rmp/test/Nangate45/Nangate45_typ.lib
read_lef src/rmp/test/Nangate45/Nangate45.lef
read_lef src/rmp/test/Nangate45/Nangate45_stdcell.lef
read_verilog src/rmp/test/aes_nangate45.v
link_design aes_cipher_top
read_sdc src/rmp/test/aes_nangate45.sdc
44 changes: 41 additions & 3 deletions src/rmp/test/cpp/TestAbc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "db_sta/MakeDbSta.hh"
#include "db_sta/dbReadVerilog.hh"
#include "db_sta/dbSta.hh"
#include "delay_optimization_strategy.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "logic_extractor.h"
Expand All @@ -33,6 +34,7 @@
#include "sta/NetworkClass.hh"
#include "sta/Sta.hh"
#include "sta/Units.hh"
#include "sta/VerilogWriter.hh"
#include "utl/Logger.h"
#include "utl/deleter.h"

Expand Down Expand Up @@ -238,8 +240,11 @@ TEST_F(AbcTest, TestLibraryInstallation)
AbcLibrary abc_library = factory.Build();

// When you set these params to zero they are essentially turned off.
abc::Abc_SclInstallGenlib(
abc_library.abc_library(), /*Slew=*/0, /*Gain=*/0, /*nGatesMin=*/0);
abc::Abc_SclInstallGenlib(abc_library.abc_library(),
/*Slew=*/0,
/*Gain=*/0,
/*fUseAll=*/0,
/*nGatesMin=*/0);
abc::Mio_LibraryTransferCellIds();
abc::Mio_Library_t* lib
= static_cast<abc::Mio_Library_t*>(abc::Abc_FrameReadLibGen());
Expand Down Expand Up @@ -457,7 +462,7 @@ TEST_F(AbcTest, InsertingMappedLogicCutDoesNotThrow)
sta::dbNetwork* network = sta_->getDbNetwork();
sta::Vertex* flop_input_vertex = nullptr;
for (sta::Vertex* vertex : *sta_->endpoints()) {
if (std::string(vertex->name(network)) == "_32989_/D") {
if (std::string(vertex->name(network)) == "_33122_/D") {
flop_input_vertex = vertex;
}
}
Expand All @@ -475,6 +480,39 @@ TEST_F(AbcTest, InsertingMappedLogicCutDoesNotThrow)
mapped_abc_network.get(), network, unique_name, &logger_));
}

TEST_F(AbcTest, InsertingMappedLogicAfterOptimizationCutDoesNotThrow)
{
AbcLibraryFactory factory(&logger_);
factory.AddDbSta(sta_.get());
AbcLibrary abc_library = factory.Build();

LoadVerilog("aes_nangate45.v", /*top=*/"aes_cipher_top");

sta::dbNetwork* network = sta_->getDbNetwork();
sta::Vertex* flop_input_vertex = nullptr;
for (sta::Vertex* vertex : *sta_->endpoints()) {
if (std::string(vertex->name(network)) == "_33122_/D") {
flop_input_vertex = vertex;
}
}
EXPECT_NE(flop_input_vertex, nullptr);

LogicExtractorFactory logic_extractor(sta_.get(), &logger_);
logic_extractor.AppendEndpoint(flop_input_vertex);
LogicCut cut = logic_extractor.BuildLogicCut(abc_library);

utl::UniquePtrWithDeleter<abc::Abc_Ntk_t> mapped_abc_network
= cut.BuildMappedAbcNetwork(abc_library, network, &logger_);

DelayOptimizationStrategy strat(sta_.get());
utl::UniquePtrWithDeleter<abc::Abc_Ntk_t> remapped
= strat.Optimize(mapped_abc_network.get(), &logger_);

rmp::UniqueName unique_name;
EXPECT_NO_THROW(cut.InsertMappedAbcNetwork(
remapped.get(), network, unique_name, &logger_));
}

TEST_F(AbcTest,
AfterExtractingAndReinsertingCuttingAgainResultsInCorrectSimulation)
{
Expand Down
2 changes: 1 addition & 1 deletion third-party/abc
Submodule abc updated 160 files

0 comments on commit 0346f68

Please sign in to comment.