refactor sdc graph annotation

This commit is contained in:
James Cherry 2020-07-11 23:56:39 -07:00
parent 57a12d9c66
commit a49dd870df
5 changed files with 115 additions and 87 deletions

View File

@ -141,6 +141,7 @@ set(STA_SOURCE
sdc/RiseFallMinMax.cc
sdc/RiseFallValues.cc
sdc/Sdc.cc
sdc/SdcGraph.cc
sdc/SdcCmdComment.cc
sdc/WriteSdc.cc

View File

@ -1367,6 +1367,8 @@ protected:
void replaceCell(Instance *inst,
Cell *to_cell,
LibertyCell *to_lib_cell);
void sdcChangedGraph();
void ensureGraphSdcAnnotated();
CmdNamespace cmd_namespace_;
Instance *current_instance_;
@ -1385,6 +1387,7 @@ protected:
bool link_make_black_boxes_;
bool update_genclks_;
EquivCells *equiv_cells_;
bool graph_sdc_annotated_;
// Singleton sta used by tcl command interpreter.
static Sta *sta_;

View File

@ -31,7 +31,6 @@
#include "Transition.hh"
#include "PortDirection.hh"
#include "Network.hh"
#include "HpinDrvrLoad.hh"
#include "RiseFallMinMax.hh"
#include "Clock.hh"
#include "ClockLatency.hh"
@ -48,6 +47,7 @@
#include "DeratingFactors.hh"
#include "search/Levelize.hh"
#include "Corner.hh"
#include "Graph.hh"
namespace sta {
@ -1301,88 +1301,6 @@ ClkHpinDisableLess::operator()(const ClkHpinDisable *disable1,
return clk_index1 < clk_index2;
}
class FindClkHpinDisables : public HpinDrvrLoadVisitor
{
public:
FindClkHpinDisables(Clock *clk,
const Network *network,
Sdc *sdc);
~FindClkHpinDisables();
bool drvrLoadExists(Pin *drvr,
Pin *load);
protected:
virtual void visit(HpinDrvrLoad *drvr_load);
void makeClkHpinDisables(Pin *clk_src,
Pin *drvr,
Pin *load);
Clock *clk_;
PinPairSet drvr_loads_;
const Network *network_;
Sdc *sdc_;
private:
DISALLOW_COPY_AND_ASSIGN(FindClkHpinDisables);
};
FindClkHpinDisables::FindClkHpinDisables(Clock *clk,
const Network *network,
Sdc *sdc) :
HpinDrvrLoadVisitor(),
clk_(clk),
network_(network),
sdc_(sdc)
{
}
FindClkHpinDisables::~FindClkHpinDisables()
{
drvr_loads_.deleteContents();
}
void
FindClkHpinDisables::visit(HpinDrvrLoad *drvr_load)
{
Pin *drvr = drvr_load->drvr();
Pin *load = drvr_load->load();
makeClkHpinDisables(drvr, drvr, load);
PinSet *hpins_from_drvr = drvr_load->hpinsFromDrvr();
PinSet::Iterator hpin_iter(hpins_from_drvr);
while (hpin_iter.hasNext()) {
Pin *hpin = hpin_iter.next();
makeClkHpinDisables(hpin, drvr, load);
}
drvr_loads_.insert(new PinPair(drvr, load));
}
void
FindClkHpinDisables::makeClkHpinDisables(Pin *clk_src,
Pin *drvr,
Pin *load)
{
ClockSet *clks = sdc_->findClocks(clk_src);
ClockSet::Iterator clk_iter(clks);
while (clk_iter.hasNext()) {
Clock *clk = clk_iter.next();
if (clk != clk_)
// Do not propagate clock from source pin if another
// clock is defined on a hierarchical pin between the
// driver and load.
sdc_->makeClkHpinDisable(clk, drvr, load);
}
}
bool
FindClkHpinDisables::drvrLoadExists(Pin *drvr,
Pin *load)
{
PinPair probe(drvr, load);
return drvr_loads_.hasKey(&probe);
}
void
Sdc::makeClkHpinDisable(Clock *clk,
Pin *drvr,

View File

@ -14,9 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "SdcGraph.hh"
#include "Stats.hh"
#include "PortDirection.hh"
#include "Network.hh"
#include "Graph.hh"
#include "DisabledPorts.hh"
#include "PortDelay.hh"
#include "ClockLatency.hh"
#include "HpinDrvrLoad.hh"
#include "Sdc.hh"
namespace sta {
@ -388,6 +394,88 @@ Sdc::clockLatency(Edge *edge,
}
}
class FindClkHpinDisables : public HpinDrvrLoadVisitor
{
public:
FindClkHpinDisables(Clock *clk,
const Network *network,
Sdc *sdc);
~FindClkHpinDisables();
bool drvrLoadExists(Pin *drvr,
Pin *load);
protected:
virtual void visit(HpinDrvrLoad *drvr_load);
void makeClkHpinDisables(Pin *clk_src,
Pin *drvr,
Pin *load);
Clock *clk_;
PinPairSet drvr_loads_;
const Network *network_;
Sdc *sdc_;
private:
DISALLOW_COPY_AND_ASSIGN(FindClkHpinDisables);
};
FindClkHpinDisables::FindClkHpinDisables(Clock *clk,
const Network *network,
Sdc *sdc) :
HpinDrvrLoadVisitor(),
clk_(clk),
network_(network),
sdc_(sdc)
{
}
FindClkHpinDisables::~FindClkHpinDisables()
{
drvr_loads_.deleteContents();
}
void
FindClkHpinDisables::visit(HpinDrvrLoad *drvr_load)
{
Pin *drvr = drvr_load->drvr();
Pin *load = drvr_load->load();
makeClkHpinDisables(drvr, drvr, load);
PinSet *hpins_from_drvr = drvr_load->hpinsFromDrvr();
PinSet::Iterator hpin_iter(hpins_from_drvr);
while (hpin_iter.hasNext()) {
Pin *hpin = hpin_iter.next();
makeClkHpinDisables(hpin, drvr, load);
}
drvr_loads_.insert(new PinPair(drvr, load));
}
void
FindClkHpinDisables::makeClkHpinDisables(Pin *clk_src,
Pin *drvr,
Pin *load)
{
ClockSet *clks = sdc_->findClocks(clk_src);
ClockSet::Iterator clk_iter(clks);
while (clk_iter.hasNext()) {
Clock *clk = clk_iter.next();
if (clk != clk_)
// Do not propagate clock from source pin if another
// clock is defined on a hierarchical pin between the
// driver and load.
sdc_->makeClkHpinDisable(clk, drvr, load);
}
}
bool
FindClkHpinDisables::drvrLoadExists(Pin *drvr,
Pin *load)
{
PinPair probe(drvr, load);
return drvr_loads_.hasKey(&probe);
}
void
Sdc::ensureClkHpinDisables()
{

View File

@ -268,7 +268,8 @@ Sta::Sta() :
power_(nullptr),
link_make_black_boxes_(true),
update_genclks_(false),
equiv_cells_(nullptr)
equiv_cells_(nullptr),
graph_sdc_annotated_(false)
{
}
@ -535,6 +536,7 @@ Sta::clear()
// Constraints reference search filter, so clear search first.
search_->clear();
sdc_->clear();
graph_sdc_annotated_ = false;
// corners are NOT cleared because they are used to index liberty files.
levelize_->clear();
if (parasitics_)
@ -1202,6 +1204,19 @@ Sta::setClockLatency(Clock *clk,
void
Sta::sdcChangedGraph()
{
if (graph_sdc_annotated_)
// Remove graph constraint annotations.
sdc_->annotateGraph(false);
graph_sdc_annotated_ = false;
}
void
Sta::ensureGraphSdcAnnotated()
{
if (!graph_sdc_annotated_) {
sdc_->annotateGraph(true);
graph_sdc_annotated_ = true;
}
}
void
@ -1421,6 +1436,7 @@ Sta::removeDataCheck(Pin *from,
void
Sta::disable(Pin *pin)
{
sdcChangedGraph();
sdc_->disable(pin);
// Levelization respects disabled edges.
levelize_->invalid();
@ -1431,6 +1447,7 @@ Sta::disable(Pin *pin)
void
Sta::removeDisable(Pin *pin)
{
sdcChangedGraph();
sdc_->removeDisable(pin);
disableAfter();
// Levelization respects disabled edges.
@ -3189,7 +3206,6 @@ Sta::ensureGraph()
makeGraph();
// Update pointers to graph.
updateComponentsState();
sdc_->annotateGraph(true);
}
return graph_;
}
@ -3205,6 +3221,7 @@ void
Sta::ensureLevelized()
{
ensureGraph();
ensureGraphSdcAnnotated();
// Need constant propagation before levelization to know edges that
// are disabled by constants.
sim_->ensureConstantsPropagated();
@ -4403,6 +4420,7 @@ void
Sta::findRegisterPreamble()
{
ensureGraph();
ensureGraphSdcAnnotated();
sim_->ensureConstantsPropagated();
}