Skip to content

Add timing paths export to Liberty #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 104 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
45f96b6
[#80124] wip: saving timing clk/output paths
magancarz Jul 9, 2025
c0f807f
[#80124] wip: saving clk-pin timing paths
magancarz Jul 9, 2025
16460c3
[#80124] prototype of printing timing paths vertices
magancarz Jul 10, 2025
00cda6c
[#80124] save simple setuphold timing paths to liberty
magancarz Jul 10, 2025
b572e75
[#80124] add extracting timing path slack and data arrival time values
magancarz Jul 10, 2025
d99f85d
[#80124] wip: exporting slack, data arrival time and data required ti…
magancarz Jul 11, 2025
35314da
[#80124] add distinction between data arrival and data required paths
magancarz Jul 11, 2025
065869b
[#80124] add saving data required path
magancarz Jul 11, 2025
9de13c6
[#80124] separate setup/hold timing path infos
magancarz Jul 11, 2025
3ca00ef
[#80124] wip: clk-output timing paths
magancarz Jul 14, 2025
e434d29
[#80124] change the way of saving worst slack timing path so OpenSTA …
magancarz Jul 15, 2025
60d887e
[#80124] test extracting worst slack path slack value from liberty
magancarz Jul 15, 2025
812c0c0
Revert "[#80124] change the way of saving worst slack timing path so …
magancarz Jul 16, 2025
2d0fd6a
[#80124] save timing paths in a subgroup
magancarz Jul 16, 2025
4063508
[#80124] clean up timing path merging code
magancarz Jul 16, 2025
6c8b290
[#80124] make timing paths saving more universal
magancarz Jul 16, 2025
b561489
[#80124] save timing paths time values as floats
magancarz Jul 16, 2025
5650578
[#80124] save read timing paths values to TimingArcAttrs
magancarz Jul 16, 2025
27b072e
[#80478] add initial version of saving register - output timing paths
magancarz Jul 16, 2025
f8cf596
[#80124] save vertices arrival time
magancarz Jul 16, 2025
21cf79c
[#80124] wip: saving combinational timing paths
magancarz Jul 16, 2025
96c82a7
[#80124] fetch design clock to calculate combinational path slack
magancarz Jul 17, 2025
90a2255
[#80124] add reading delay and combinational paths
magancarz Jul 18, 2025
7e35315
[#80124] wip: using previously exported timing paths in timing checks
magancarz Jul 18, 2025
2a0ec4c
[#80124] convert loaded timing path parameters to correct time unit
magancarz Jul 18, 2025
39a82e4
[#80124] wip: save data required path margin for now
magancarz Jul 18, 2025
dc3d1b3
[#80124] add test files
magancarz Jul 18, 2025
56869cb
[#80124] wip: comparing exported timing paths with calculated delays
magancarz Jul 18, 2025
54aa8dd
[#80124] add cell data paths information while reporting paths
magancarz Jul 21, 2025
399a1f9
[#80124] wip: working on reporting from and to cell timing paths
magancarz Jul 21, 2025
aa34963
[#80791] wip: display timing paths: add more info
magancarz Jul 22, 2025
4f3d4dc
[#80124] fix calculating slack for register - output timing paths
magancarz Jul 22, 2025
634bc8a
[#80791] move common report timing path code to a function
magancarz Jul 22, 2025
0a079ae
[#80791] save worst slack timing path vertices transitions
magancarz Jul 23, 2025
cba8383
[#80791] print timing paths vertices transitions
magancarz Jul 23, 2025
03c949c
Revert "[#80124] wip: comparing exported timing paths with calculated…
magancarz Jul 23, 2025
1d9d6cb
[#80124] fix exported timing path vertex transition
magancarz Jul 23, 2025
fd42bf0
[#80791] initial version for including timing path vertices
magancarz Jul 23, 2025
698e81a
[#80124] add saving rise and fall worst timing paths separately
magancarz Jul 23, 2025
92da85d
Revert "[#80124] wip: using previously exported timing paths in timin…
magancarz Jul 24, 2025
1f7ba77
[#80124] change name of timing paths group to paths
magancarz Jul 24, 2025
b525534
[#80124] update liberty reader to parse rise and fall timing paths
magancarz Jul 24, 2025
77b99e1
[#80791] update reporting paths to use rise/fall timing paths from li…
magancarz Jul 24, 2025
7e12e81
[#80124] update example files for timing paths
magancarz Jul 24, 2025
26a2e1e
[#80791] add timing arcs sanity guards
magancarz Jul 24, 2025
4e913fb
[#80791] remove unnecessary dash line from report
magancarz Jul 24, 2025
26faa28
[#80791] add example files for timing paths and report checks
magancarz Jul 24, 2025
6e3225e
[#80791] restore base example files
magancarz Jul 24, 2025
f9c1d1e
[#80124] clean up timing paths extraction code
magancarz Jul 24, 2025
da25d99
[#80124] clean up timing paths writing and reading code
magancarz Jul 24, 2025
4dce5ad
[#80791] change way of accessing path end check arc
magancarz Jul 24, 2025
10d9c68
[#80791] take exported timing paths into reported paths data arrival …
magancarz Jul 24, 2025
d00f9cd
[#80791] add example with comb cell in the middle
magancarz Jul 24, 2025
722bdf8
[#80791] fix mid comb case while unwrapping timing paths
magancarz Jul 25, 2025
9af6611
[#80791] remove unused files
magancarz Jul 25, 2025
4ffc49e
[#80791] omit saving instance timing arc if not valid
magancarz Jul 25, 2025
3f8c3f1
[#80791] fix write_timing_model_scalar test
magancarz Jul 25, 2025
9238d5b
[#80124] add tests for dff and comb cells
magancarz Jul 25, 2025
6a95143
[#80791] fix unwrapping last instance and clean up forwarding code
magancarz Jul 25, 2025
09ccf12
[#80791] add timing_cell_complex test
magancarz Jul 25, 2025
497ee1a
[#80791] wip: inlining timing path vertices in json reported paths
magancarz Jul 25, 2025
dcc229a
[#80124] add saving slew, capacitance, pin, cell, instance and net
magancarz Jul 28, 2025
2cee684
[#80124] add saving if pin is a driver
magancarz Jul 28, 2025
0327053
[#80791] add displaying cap, slew and net fields
magancarz Jul 28, 2025
632e10e
[#80124] use timing paths names from one place
magancarz Jul 28, 2025
ed29e5c
[#80124] take net and instance names from proper networks
magancarz Jul 28, 2025
bd753df
[#80791] use exported timing path's parameters while exporting to json
magancarz Jul 28, 2025
13a55ac
[#80791] wip: working on target clk path
magancarz Jul 28, 2025
b8f67dc
[#80791] use rise/fall from vertex
magancarz Jul 28, 2025
1a1fcb1
[#80791] add more example files
magancarz Jul 29, 2025
814b463
[#80791] remove unused variables
magancarz Jul 29, 2025
c3093f7
[#80791] use data required path when reporting clock path in json format
magancarz Jul 29, 2025
74e27e3
[#80791] use startpoint and endpoint from timing paths
magancarz Jul 29, 2025
eff2f56
[#80791] update test files
magancarz Jul 29, 2025
2557772
[#80791] update ReportPath's pathStartpoint and pathEndpoint function…
magancarz Jul 29, 2025
0e227f2
[#80791] update report_json1 test files
magancarz Jul 29, 2025
4923390
[#80791] use previous path arrival when inlining vertices in json format
magancarz Jul 29, 2025
92c16a1
[#80791] remove unused files
magancarz Jul 30, 2025
dab3fa1
[#80791] use slack merging instead of setting
magancarz Jul 30, 2025
3ba903e
[#80791] clean up the code and add more complexity to the timing_cell…
magancarz Jul 30, 2025
7acc2e5
[#80791] add timing_cell_complex_json test
magancarz Jul 30, 2025
33757e4
[#80791] fix cases of misaligned tabs/spaces
magancarz Jul 30, 2025
ab29877
[#80124] resolve some of the suggestions
magancarz Aug 1, 2025
ea94fb2
[#81462] apply test files style suggestions
magancarz Aug 5, 2025
e498909
[#81462] remove nangate lib from test directory and use asap7_small i…
magancarz Aug 5, 2025
549abca
[#81462] add comment to indicate custom Liberty attrs/groups
magancarz Aug 5, 2025
3470ef7
[#81462] revert using inlined vertices as startpoints/endpoints
magancarz Aug 5, 2025
02ff607
[#81462] use CombinationalTimingPath in register-output case
magancarz Aug 5, 2025
7848b37
[#81462] clean up saving timing paths and checking if timing paths ar…
magancarz Aug 6, 2025
5cb1ecc
[#81462] add flag for enabling/disabling exporting timing paths
magancarz Aug 6, 2025
bcd4041
[#81462] add CDC test for timing paths
magancarz Aug 6, 2025
1460d7a
[#81462] simplify skipping unwrapped cell pins
magancarz Aug 6, 2025
f88022a
[#81462] wip: internal paths: iterate over reg2reg internal paths and…
magancarz Aug 6, 2025
0240c87
[#81462] wip: internal paths: add saving worst internal path to liberty
magancarz Aug 6, 2025
31fb39e
[#81462] wip: internal paths: add testing example
magancarz Aug 6, 2025
fd382a1
[#81462] wip: internal paths: start timing path from DFF clock vertex
magancarz Aug 6, 2025
f273ce4
[#81462] wip: internal paths: save worst paths for minmax/risefall cases
magancarz Aug 6, 2025
686c716
[#81462] wip: internal paths: create register input/output pins pairs
magancarz Aug 7, 2025
3e2bfd0
[#81462] wip: internal paths: fix writing multiple internal paths
magancarz Aug 7, 2025
19e01a1
[#81462] wip: internal paths: add reading cell reg2reg worst timing p…
magancarz Aug 7, 2025
763fdd3
[#81462] internal paths: fix target transition type filter
magancarz Aug 7, 2025
96b58d8
[#81462] take in consideration if clock is propagated
magancarz Aug 8, 2025
2d7f4de
[#81462] wip: testing propagated clock timing paths
magancarz Aug 8, 2025
1d432c7
[#81462] update test ground truth files
magancarz Aug 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 192 additions & 0 deletions examples/timing_cell_dff.lib
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
library (timing_cell_dff) {
comment : "";
delay_model : table_lookup;
simulation : false;
capacitive_load_unit (1,fF);
leakage_power_unit : 1pW;
current_unit : "1mA";
pulling_resistance_unit : "1kohm";
time_unit : "1ns";
voltage_unit : "1v";
library_features(report_delay_calculation);

input_threshold_pct_rise : 50;
input_threshold_pct_fall : 50;
output_threshold_pct_rise : 50;
output_threshold_pct_fall : 50;
slew_lower_threshold_pct_rise : 30;
slew_lower_threshold_pct_fall : 30;
slew_upper_threshold_pct_rise : 70;
slew_upper_threshold_pct_fall : 70;
slew_derate_from_library : 1.0;


nom_process : 1.0;
nom_temperature : 125.0;
nom_voltage : 0.95;

lu_table_template(template_1) {
variable_1 : total_output_net_capacitance;
index_1("0.36562, 1.89781, 3.79562, 7.59125, 15.18250, 30.36500, 60.73000");
}

cell ("timing_cell_dff") {
area : 11.438
is_macro_cell : true;
pin("in") {
direction : input;
capacitance : 0.9346;
timing() {
related_pin : "clk";
timing_type : hold_rising;
rise_constraint(scalar) {
values("-0.02757");
}
fall_constraint(scalar) {
values("-0.07072");
}
paths() {
slack : 0.02757;
fall_data_required() {
time: 0.00300;
vertex("r1", "DFF_X1", "r1/CK", "clk", "^", 0.00000, 0.00000, 1.64207, 0);
}
fall_data_arrival() {
time: 0.07373;
vertex("", "timing_cell_dff", "in", "", "v", 0.00000, 0.00000, 0.83524, 1);
vertex("u1", "BUF_X1", "u1/A", "in", "v", 0.00000, 0.00000, 0.83524, 0);
vertex("u1", "BUF_X1", "u1/Z", "w1", "v", 0.07373, 0.01504, 1.03013, 1);
vertex("r1", "DFF_X1", "r1/D", "w1", "v", 0.07373, 0.01504, 1.03013, 0);
}
rise_data_required() {
time: 0.01713;
vertex("r1", "DFF_X1", "r1/CK", "clk", "^", 0.00000, 0.00000, 1.81915, 0);
}
rise_data_arrival() {
time: 0.04470;
vertex("", "timing_cell_dff", "in", "", "^", 0.00000, 0.00000, 0.93456, 1);
vertex("u1", "BUF_X1", "u1/A", "in", "^", 0.00000, 0.00000, 0.93456, 0);
vertex("u1", "BUF_X1", "u1/Z", "w1", "^", 0.04470, 0.01908, 1.10913, 1);
vertex("r1", "DFF_X1", "r1/D", "w1", "^", 0.04470, 0.01908, 1.10913, 0);
}
}
}
timing() {
related_pin : "clk";
timing_type : setup_rising;
rise_constraint(scalar) {
values("0.11670");
}
fall_constraint(scalar) {
values("0.23045");
}
paths() {
slack : 9.76955;
fall_data_required() {
time: 9.84328;
vertex("r1", "DFF_X1", "r1/CK", "clk", "^", 0.00000, 0.00000, 1.64207, 0);
}
fall_data_arrival() {
time: 0.07373;
vertex("", "timing_cell_dff", "in", "", "v", 0.00000, 0.00000, 0.83524, 1);
vertex("u1", "BUF_X1", "u1/A", "in", "v", 0.00000, 0.00000, 0.83524, 0);
vertex("u1", "BUF_X1", "u1/Z", "w1", "v", 0.07373, 0.01504, 1.03013, 1);
vertex("r1", "DFF_X1", "r1/D", "w1", "v", 0.07373, 0.01504, 1.03013, 0);
}
rise_data_required() {
time: 9.92800;
vertex("r1", "DFF_X1", "r1/CK", "clk", "^", 0.00000, 0.00000, 1.81915, 0);
}
rise_data_arrival() {
time: 0.04470;
vertex("", "timing_cell_dff", "in", "", "^", 0.00000, 0.00000, 0.93456, 1);
vertex("u1", "BUF_X1", "u1/A", "in", "^", 0.00000, 0.00000, 0.93456, 0);
vertex("u1", "BUF_X1", "u1/Z", "w1", "^", 0.04470, 0.01908, 1.10913, 1);
vertex("r1", "DFF_X1", "r1/D", "w1", "^", 0.04470, 0.01908, 1.10913, 0);
}
}
}
}
pin("clk") {
direction : input;
clock : true;
capacitance : 1.8192;
timing() {
timing_sense : positive_unate;
timing_type : min_clock_tree_path;
cell_rise(scalar) {
values("0.00000");
}
cell_fall(scalar) {
values("0.00000");
}
}
timing() {
timing_sense : positive_unate;
timing_type : max_clock_tree_path;
cell_rise(scalar) {
values("0.00000");
}
cell_fall(scalar) {
values("0.00000");
}
}
}
pin("out") {
direction : output;
capacitance : 0.0000;
timing() {
related_pin : "clk";
timing_type : rising_edge;
cell_rise(template_1) {
index_1("0.36562, 1.89781, 3.79562, 7.59125, 15.18250, 30.36500, 60.73000");
values("0.29101,0.30130,0.31279,0.33950,0.39956,0.52522,0.77978");
}
rise_transition(template_1) {
index_1("0.36562, 1.89781, 3.79562, 7.59125, 15.18250, 30.36500, 60.73000");
values("0.01964,0.02937,0.04223,0.07118,0.13205,0.25458,0.49990");
}
cell_fall(template_1) {
index_1("0.36562, 1.89781, 3.79562, 7.59125, 15.18250, 30.36500, 60.73000");
values("0.23051,0.23926,0.24731,0.26050,0.28251,0.32097,0.39267");
}
fall_transition(template_1) {
index_1("0.36562, 1.89781, 3.79562, 7.59125, 15.18250, 30.36500, 60.73000");
values("0.01522,0.01891,0.02276,0.03000,0.04411,0.07298,0.13352");
}
paths() {
slack : 0.22842;
fall_clocked_output() {
time: 0.22842;
vertex("r2", "DFF_X1", "r2/CK", "clk", "^", 0.00000, 0.00000, 1.64207, 0);
vertex("r2", "DFF_X1", "r2/Q", "out", "v", 0.22842, 0.01434, 0.00000, 1);
vertex("", "timing_cell_dff", "out", "", "v", 0.22842, 0.01434, 0.00000, 0);
}
rise_clocked_output() {
time: 0.28855;
vertex("r2", "DFF_X1", "r2/CK", "clk", "^", 0.00000, 0.00000, 1.81915, 0);
vertex("r2", "DFF_X1", "r2/Q", "out", "^", 0.28855, 0.01732, 0.00000, 1);
vertex("", "timing_cell_dff", "out", "", "^", 0.28855, 0.01732, 0.00000, 0);
}
}
}
}
worst_slack_path() {
slack : 0.09420;
rise_data_arrival() {
time: 0.11136;
vertex("r1", "DFF_X1", "r1/Q", "w2", "^", 0.00000, 0.02325, 0.93456, 1);
vertex("u2", "BUF_X1", "u2/A", "w2", "^", 0.00000, 0.02325, 0.93456, 0);
vertex("u2", "BUF_X1", "u2/Z", "w3", "^", 0.05639, 0.01783, 0.93456, 1);
vertex("u3", "BUF_X1", "u3/A", "w3", "^", 0.05639, 0.01783, 0.93456, 0);
vertex("u3", "BUF_X1", "u3/Z", "w4", "^", 0.11136, 0.01913, 1.10913, 1);
vertex("r2", "DFF_X1", "r2/D", "w4", "^", 0.11136, 0.01913, 1.10913, 0);
}
rise_data_required() {
time: 0.01716;
vertex("r2", "DFF_X1", "r2/CK", "clk", "^", 0.00000, 0.00000, 1.81915, 0);
}
}
}

}
8 changes: 8 additions & 0 deletions examples/timing_cell_dff.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# timing cell dff example
read_liberty nangate45_slow.lib.gz
read_verilog timing_cell_dff.v
link_design timing_cell_dff
create_clock -name clk -period 10 {clk}
set_input_delay -clock clk 0 {in}
write_timing_model -paths timing_cell_dff.lib
report_checks -path_delay min_rise -from r1/Q
16 changes: 16 additions & 0 deletions examples/timing_cell_dff.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module timing_cell_dff (in, clk, out);

input in, clk;
output out;
wire w1, w2, w3, w4;

BUF_X1 u1 (.A(in), .Z(w1));

DFF_X1 r1 (.D(w1), .CK(clk), .Q(w2));

BUF_X1 u2 (.A(w2), .Z(w3));
BUF_X1 u3 (.A(w3), .Z(w4));

DFF_X1 r2 (.D(w4), .CK(clk), .Q(out));

endmodule
10 changes: 10 additions & 0 deletions include/sta/Liberty.hh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "Transition.hh"
#include "Delay.hh"
#include "LibertyClass.hh"
#include "TimingArc.hh"

namespace sta {

Expand Down Expand Up @@ -561,6 +562,13 @@ public:
const char *userFunctionClass() const;
void setUserFunctionClass(const char *user_function_class);

void setWorstSlackTimingPath(const InputRegisterTimingPath& timing_path,
const MinMax *min_max,
const RiseFall *rise_fall);
const InputRegisterTimingPath &getWorstSlackTimingPath(const MinMax *min_max,
const RiseFall *rise_fall) const;
bool hasWorstSlackTimingPaths() const;

protected:
void addPort(ConcretePort *port);
void setHasInternalPorts(bool has_internal);
Expand Down Expand Up @@ -652,6 +660,8 @@ protected:
std::mutex waveform_lock_;
std::string footprint_;
std::string user_function_class_;
float worst_slack_{std::numeric_limits<float>::max()};
std::array<std::array<InputRegisterTimingPath, 2>, 2> worst_slack_timing_paths_;

private:
friend class LibertyLibrary;
Expand Down
3 changes: 2 additions & 1 deletion include/sta/LibertyWriter.hh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class StaState;
void
writeLiberty(LibertyLibrary *lib,
const char *filename,
StaState *sta);
StaState *sta,
bool write_timing_paths);

} // namespace
3 changes: 2 additions & 1 deletion include/sta/Sta.hh
Original file line number Diff line number Diff line change
Expand Up @@ -1248,7 +1248,8 @@ public:
const char *cell_name,
const char *filename,
const Corner *corner,
const bool scalar);
const bool scalar,
const bool paths);

// Find equivalent cells in equiv_libs.
// Optionally add mappings for cells in map_libs.
Expand Down
66 changes: 66 additions & 0 deletions include/sta/TimingArc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@
#pragma once

#include <memory>
#include <unordered_map>
#include <limits>

#include "Vector.hh"
#include "Transition.hh"
#include "Delay.hh"
#include "LibertyClass.hh"
#include "TimingRole.hh"

namespace sta {

Expand Down Expand Up @@ -93,6 +96,58 @@ timingTypeScaleFactorType(TimingType type);

////////////////////////////////////////////////////////////////

struct TimingPathVertex
{
std::string instance;
std::string cell;
std::string pin;
std::string net;
std::string transition;
float arrival;
float slew;
float capacitance;
bool is_driver;
};

struct TimingPath
{
std::string name{};
std::vector<TimingPathVertex> vertices{};
float time{0.0f};
const RiseFall* rise_fall;

struct Names
{
static constexpr std::array<const char*, 2> DATA_ARRIVAL{"rise_data_arrival", "fall_data_arrival"};
static constexpr std::array<const char*, 2> DATA_REQUIRED{"rise_data_required", "fall_data_required"};
static constexpr std::array<const char*, 2> CLOCKED_OUTPUT{"rise_clocked_output", "fall_clocked_output"};
static constexpr std::array<const char*, 2> COMBINATIONAL{"rise_combinational", "fall_combinational"};
};

inline static const std::unordered_map<const TimingRole*, std::array<const char*, 2>> ROLE_PATH_MAPPINGS =
{
{TimingRole::regClkToQ(), Names::CLOCKED_OUTPUT},
{TimingRole::combinational(), Names::COMBINATIONAL},
{TimingRole::setup(), Names::DATA_ARRIVAL},
{TimingRole::hold(), Names::DATA_ARRIVAL}
};
};

struct InputRegisterTimingPath
{
float slack{std::numeric_limits<float>::max()};
TimingPath data_arrival_path{};
TimingPath data_required_path{};
};

struct CombinationalTimingPath
{
float slack{std::numeric_limits<float>::max()};
TimingPath combinational_delay_path{};
};

////////////////////////////////////////////////////////////////

class TimingArcAttrs
{
public:
Expand Down Expand Up @@ -120,6 +175,11 @@ public:
TimingModel *model);
float ocvArcDepth() const { return ocv_arc_depth_; }
void setOcvArcDepth(float depth);
void setSlack(float slack);
void mergeSlack(float slack);
void addTimingPath(TimingPath timing_path);
float slack() const { return slack_; }
const std::unordered_map<std::string, TimingPath>& timingPaths() const { return timing_paths_; }

protected:
TimingType timing_type_;
Expand All @@ -132,6 +192,8 @@ protected:
const char *mode_value_;
float ocv_arc_depth_;
TimingModel *models_[RiseFall::index_count];
float slack_{std::numeric_limits<float>::max()};
std::unordered_map<std::string, TimingPath> timing_paths_;
};

// A timing arc set is a group of related timing arcs between from/to
Expand Down Expand Up @@ -184,6 +246,10 @@ public:
const char *sdfCondEnd() const { return attrs_->sdfCondEnd(); }
const char *modeName() const { return attrs_->modeName(); }
const char *modeValue() const { return attrs_->modeValue(); }
float slack() const { return attrs_->slack(); }
bool hasTimingPaths() const { return !attrs_->timingPaths().empty(); }
const std::unordered_map<std::string, TimingPath>& timingPaths() const { return attrs_->timingPaths(); }

// Timing arc set index in cell.
TimingArcIndex index() const { return index_; }
bool isDisabledConstraint() const { return is_disabled_constraint_; }
Expand Down
Loading