examples
This commit is contained in:
parent
5a5164276e
commit
e2d02839a3
BIN
doc/OpenSTA.odt
BIN
doc/OpenSTA.odt
Binary file not shown.
BIN
doc/OpenSTA.pdf
BIN
doc/OpenSTA.pdf
Binary file not shown.
|
|
@ -0,0 +1,93 @@
|
|||
(DELAYFILE
|
||||
(SDFVERSION "OVI 2.1")
|
||||
(DESIGN "top")
|
||||
(DATE "Thu Mar 2 20:33:26 2000")
|
||||
(VENDOR "slow")
|
||||
(PROGRAM "Hand job")
|
||||
(VERSION "69")
|
||||
(DIVIDER /)
|
||||
(VOLTAGE 2.25:2.25:2.25)
|
||||
(PROCESS "1.000:1.000:1.000")
|
||||
(TEMPERATURE 125.00:125.00:125.00)
|
||||
(TIMESCALE 1ns)
|
||||
(CELL
|
||||
(CELLTYPE "top")
|
||||
(INSTANCE)
|
||||
(DELAY
|
||||
(ABSOLUTE
|
||||
// Offset in1 vs in2, rise vs fall arrivals so results are deterministic.
|
||||
(INTERCONNECT in1 r1/D (0.011:0.011:0.011) (0.01:0.01:0.01))
|
||||
(INTERCONNECT in2 r2/D (0.021:0.021:0.021) (0.02:0.02:0.02))
|
||||
(INTERCONNECT clk1 r1/CK (0.0:0.0:0.0) (0.0:0.0:0.0))
|
||||
(INTERCONNECT clk2 r2/CK (0.0:0.0:0.0) (0.0:0.0:0.0))
|
||||
(INTERCONNECT clk3 r3/CK (0.0:0.0:0.0) (0.0:0.0:0.0))
|
||||
(INTERCONNECT r1/Q u2/A1 (0.0:0.0:0.0) (0.0:0.0:0.0))
|
||||
(INTERCONNECT r2/Q u1/A (0.0:0.0:0.0) (0.0:0.0:0.0))
|
||||
(INTERCONNECT u1/Z u2/A2 (0.0:0.0:0.0) (0.0:0.0:0.0))
|
||||
(INTERCONNECT u2/ZN r3/D (0.0:0.0:0.0) (0.0:0.0:0.0))
|
||||
(INTERCONNECT r3/Q out (0.0:0.0:0.0) (0.0:0.0:0.0))
|
||||
)
|
||||
)
|
||||
)
|
||||
(CELL
|
||||
(CELLTYPE "DFF_X1")
|
||||
(INSTANCE r1)
|
||||
(DELAY
|
||||
(ABSOLUTE
|
||||
(IOPATH CK Q (1:1:1) (1.1:1.1:1.1))
|
||||
)
|
||||
)
|
||||
(TIMINGCHECK
|
||||
(SETUP D (posedge CK) (.5:.5:.5))
|
||||
(HOLD D (posedge CK) (.1:.1:.1))
|
||||
(PERIOD (posedge CK) (1.0:2.0:3.0))
|
||||
)
|
||||
)
|
||||
(CELL
|
||||
(CELLTYPE "DFF_X1")
|
||||
(INSTANCE r2)
|
||||
(DELAY
|
||||
(ABSOLUTE
|
||||
(IOPATH CK Q (1:1:1) (1.1:1.1:1.1))
|
||||
)
|
||||
)
|
||||
(TIMINGCHECK
|
||||
(SETUP D (posedge CK) (.5:.5:.5))
|
||||
(HOLD D (posedge CK) (.1:.1:.1))
|
||||
(PERIOD (posedge CK) (1.0:2.0:3.0))
|
||||
)
|
||||
)
|
||||
(CELL
|
||||
(CELLTYPE "DFF_X1")
|
||||
(INSTANCE r3)
|
||||
(DELAY
|
||||
(ABSOLUTE
|
||||
(IOPATH CK Q (1:1:1) (1.1:1.1:1.1))
|
||||
)
|
||||
)
|
||||
(TIMINGCHECK
|
||||
(SETUP D (posedge CK) (.5:.5:.5))
|
||||
(HOLD D (posedge CK) (.1:.1:.1))
|
||||
(PERIOD (posedge CK) (1.0:2.0:3.0))
|
||||
)
|
||||
)
|
||||
(CELL
|
||||
(CELLTYPE "BUF_X1")
|
||||
(INSTANCE u1)
|
||||
(DELAY
|
||||
(ABSOLUTE
|
||||
(IOPATH A Z (1:1:1) (1.1:1.1:1.1))
|
||||
)
|
||||
)
|
||||
)
|
||||
(CELL
|
||||
(CELLTYPE "AND2_X1")
|
||||
(INSTANCE u2)
|
||||
(DELAY
|
||||
(ABSOLUTE
|
||||
(IOPATH A1 ZN (1:1:1) (1.1:1.1:1.1))
|
||||
(IOPATH A2 ZN (1:1:1) (1.1:1.1:1.1))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# sdf example
|
||||
read_liberty example1_slow.lib
|
||||
read_verilog example1.v
|
||||
link_design top
|
||||
read_sdf example1.sdf
|
||||
create_clock -name clk -period 10 {clk1 clk2 clk3}
|
||||
set_input_delay -clock clk 0 {in1 in2}
|
||||
report_checks
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
module top (in1, in2, clk1, clk2, clk3, out);
|
||||
input in1, in2, clk1, clk2, clk3;
|
||||
output out;
|
||||
wire r1q, r2q, u1z, u2z;
|
||||
|
||||
DFF_X1 r1 (.D(in1), .CK(clk1), .Q(r1q));
|
||||
DFF_X1 r2 (.D(in2), .CK(clk2), .Q(r2q));
|
||||
BUF_X1 u1 (.A(r2q), .Z(u1z));
|
||||
AND2_X1 u2 (.A1(r1q), .A2(u1z), .ZN(u2z));
|
||||
DFF_X1 r3 (.D(u2z), .CK(clk3), .Q(out));
|
||||
endmodule // top
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# delay calc example
|
||||
read_liberty example1_slow.lib
|
||||
read_verilog example1.v
|
||||
link_design top
|
||||
create_clock -name clk -period 10 {clk1 clk2 clk3}
|
||||
set_input_delay -clock clk 0 {in1 in2}
|
||||
report_checks
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# min/max delay calc example
|
||||
read_liberty -max example1_slow.lib
|
||||
read_liberty -min example1_fast.lib
|
||||
read_verilog example1.v
|
||||
link_design top
|
||||
create_clock -name clk -period 10 {clk1 clk2 clk3}
|
||||
set_input_delay -clock clk 0 {in1 in2}
|
||||
report_checks -path_delay min_max
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# delay calc example with parasitics
|
||||
read_liberty example1_slow.lib
|
||||
read_verilog example1.v
|
||||
link_design top
|
||||
read_spef example1.dspef
|
||||
create_clock -name clk -period 10 {clk1 clk2 clk3}
|
||||
set_input_delay -clock clk 0 {in1 in2}
|
||||
report_checks
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# 3 corner with +/- 10% derating example
|
||||
define_corners wc typ bc
|
||||
read_liberty -corner wc example1_slow.lib
|
||||
read_liberty -corner typ example1_typ.lib
|
||||
read_liberty -corner bc example1_fast.lib
|
||||
read_verilog example1.v
|
||||
link_design top
|
||||
set_timing_derate -early 0.9
|
||||
set_timing_derate -early 1.1
|
||||
create_clock -name clk -period 10 {clk1 clk2 clk3}
|
||||
set_input_delay -clock clk 0 {in1 in2}
|
||||
report_checks -path_delay min_max
|
||||
report_checks -corner typ
|
||||
|
|
@ -128,11 +128,8 @@ LibertyLibrary::~LibertyLibrary()
|
|||
delete units_;
|
||||
ocv_derate_map_.deleteContents();
|
||||
|
||||
SupplyVoltageMap::Iterator supply_iter(supply_voltage_map_);
|
||||
while (supply_iter.hasNext()) {
|
||||
const char *supply_name;
|
||||
float voltage;
|
||||
supply_iter.next(supply_name, voltage);
|
||||
for (auto name_volt : supply_voltage_map_) {
|
||||
const char *supply_name = name_volt.first;
|
||||
stringDelete(supply_name);
|
||||
}
|
||||
}
|
||||
|
|
@ -725,10 +722,8 @@ LibertyLibrary::makeCornerMap(LibertyCell *cell1,
|
|||
cell2->name());
|
||||
}
|
||||
|
||||
LibertyCellTimingArcSetIterator set_iter1(cell1);
|
||||
while (set_iter1.hasNext()) {
|
||||
TimingArcSet *arc_set1 = set_iter1.next();
|
||||
TimingArcSet *arc_set2 = cell2->findTimingArcSet(arc_set1);
|
||||
for (auto arc_set1 : cell1->timing_arc_sets_) {
|
||||
auto arc_set2 = cell2->findTimingArcSet(arc_set1);
|
||||
if (arc_set2) {
|
||||
if (link) {
|
||||
TimingArcSetArcIterator arc_iter1(arc_set1);
|
||||
|
|
@ -847,18 +842,8 @@ LibertyCell::LibertyCell(LibertyLibrary *library,
|
|||
has_internal_ports_(false),
|
||||
interface_timing_(false),
|
||||
clock_gate_type_(ClockGateType::none),
|
||||
timing_arc_sets_(nullptr),
|
||||
port_timing_arc_set_map_(nullptr),
|
||||
timing_arc_set_from_map_(nullptr),
|
||||
timing_arc_set_to_map_(nullptr),
|
||||
has_infered_reg_timing_arcs_(false),
|
||||
internal_powers_(nullptr),
|
||||
leakage_powers_(nullptr),
|
||||
sequentials_(nullptr),
|
||||
port_to_seq_map_(nullptr),
|
||||
mode_defs_(nullptr),
|
||||
scale_factors_(nullptr),
|
||||
scaled_cells_(nullptr),
|
||||
test_cell_(nullptr),
|
||||
ocv_arc_depth_(0.0),
|
||||
ocv_derate_(nullptr),
|
||||
|
|
@ -869,59 +854,22 @@ LibertyCell::LibertyCell(LibertyLibrary *library,
|
|||
|
||||
LibertyCell::~LibertyCell()
|
||||
{
|
||||
if (mode_defs_) {
|
||||
mode_defs_->deleteContents();
|
||||
delete mode_defs_;
|
||||
}
|
||||
|
||||
mode_defs_.deleteContents();
|
||||
latch_d_to_q_map_.deleteContents();
|
||||
|
||||
deleteTimingArcAttrs();
|
||||
if (timing_arc_sets_) {
|
||||
timing_arc_sets_->deleteContents();
|
||||
delete timing_arc_sets_;
|
||||
delete timing_arc_set_map_;
|
||||
|
||||
LibertyPortPairTimingArcMap::Iterator port_map_iter(port_timing_arc_set_map_);
|
||||
while (port_map_iter.hasNext()) {
|
||||
LibertyPortPair *port_pair;
|
||||
TimingArcSetSeq *sets;
|
||||
port_map_iter.next(port_pair, sets);
|
||||
delete port_pair;
|
||||
delete sets;
|
||||
}
|
||||
delete port_timing_arc_set_map_;
|
||||
|
||||
timing_arc_set_from_map_->deleteContents();
|
||||
delete timing_arc_set_from_map_;
|
||||
|
||||
timing_arc_set_to_map_->deleteContents();
|
||||
delete timing_arc_set_to_map_;
|
||||
}
|
||||
timing_arc_sets_.deleteContents();
|
||||
port_timing_arc_set_map_.deleteContents();
|
||||
timing_arc_set_from_map_.deleteContents();
|
||||
timing_arc_set_to_map_.deleteContents();
|
||||
|
||||
deleteInternalPowerAttrs();
|
||||
if (internal_powers_) {
|
||||
internal_powers_->deleteContents();
|
||||
delete internal_powers_;
|
||||
}
|
||||
|
||||
if (leakage_powers_) {
|
||||
leakage_powers_->deleteContents();
|
||||
delete leakage_powers_;
|
||||
}
|
||||
|
||||
if (sequentials_) {
|
||||
sequentials_->deleteContents();
|
||||
delete sequentials_;
|
||||
delete port_to_seq_map_;
|
||||
}
|
||||
internal_powers_.deleteContents();
|
||||
leakage_powers_.deleteContents();
|
||||
|
||||
sequentials_.deleteContents();
|
||||
bus_dcls_.deleteContents();
|
||||
|
||||
if (scaled_cells_) {
|
||||
scaled_cells_->deleteContents();
|
||||
delete scaled_cells_;
|
||||
}
|
||||
scaled_cells_.deleteContents();
|
||||
|
||||
delete test_cell_;
|
||||
ocv_derate_map_.deleteContents();
|
||||
|
|
@ -935,9 +883,7 @@ LibertyCell::~LibertyCell()
|
|||
void
|
||||
LibertyCell::deleteTimingArcAttrs()
|
||||
{
|
||||
TimingArcAttrsSeq::Iterator attr_iter(timing_arc_attrs_);
|
||||
while (attr_iter.hasNext()) {
|
||||
TimingArcAttrs *attrs = attr_iter.next();
|
||||
for (auto attrs : timing_arc_attrs_) {
|
||||
attrs->deleteContents();
|
||||
delete attrs;
|
||||
}
|
||||
|
|
@ -992,16 +938,14 @@ ModeDef *
|
|||
LibertyCell::makeModeDef(const char *name)
|
||||
{
|
||||
ModeDef *mode = new ModeDef(name);
|
||||
if (mode_defs_ == nullptr)
|
||||
mode_defs_ = new ModeDefMap;
|
||||
(*mode_defs_)[mode->name()] = mode;
|
||||
mode_defs_[mode->name()] = mode;
|
||||
return mode;
|
||||
}
|
||||
|
||||
ModeDef *
|
||||
LibertyCell::findModeDef(const char *name)
|
||||
{
|
||||
return mode_defs_->findKey(name);
|
||||
return mode_defs_.findKey(name);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1085,13 +1029,10 @@ LibertyCell::setClockGateType(ClockGateType type)
|
|||
unsigned
|
||||
LibertyCell::addTimingArcSet(TimingArcSet *arc_set)
|
||||
{
|
||||
if (timing_arc_sets_ == nullptr) {
|
||||
timing_arc_sets_ = new TimingArcSetSeq;
|
||||
}
|
||||
int set_index = timing_arc_sets_->size();
|
||||
int set_index = timing_arc_sets_.size();
|
||||
if (set_index > timing_arc_set_index_max)
|
||||
internalError("timing arc set max index exceeded");
|
||||
timing_arc_sets_->push_back(arc_set);
|
||||
timing_arc_sets_.push_back(arc_set);
|
||||
|
||||
LibertyPort *from = arc_set->from();
|
||||
TimingRole *role = arc_set->role();
|
||||
|
|
@ -1112,9 +1053,7 @@ LibertyCell::addTimingArcAttrs(TimingArcAttrs *attrs)
|
|||
void
|
||||
LibertyCell::addInternalPower(InternalPower *power)
|
||||
{
|
||||
if (internal_powers_ == nullptr)
|
||||
internal_powers_ = new InternalPowerSeq;
|
||||
internal_powers_->push_back(power);
|
||||
internal_powers_.push_back(power);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1126,21 +1065,16 @@ LibertyCell::addInternalPowerAttrs(InternalPowerAttrs *attrs)
|
|||
void
|
||||
LibertyCell::deleteInternalPowerAttrs()
|
||||
{
|
||||
InternalPowerAttrsSeq::Iterator attr_iter(internal_power_attrs_);
|
||||
while (attr_iter.hasNext()) {
|
||||
InternalPowerAttrs *attrs = attr_iter.next();
|
||||
for (auto attrs : internal_power_attrs_) {
|
||||
attrs->deleteContents();
|
||||
delete attrs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
LibertyCell::addLeakagePower(LeakagePower *power)
|
||||
{
|
||||
if (leakage_powers_ == nullptr)
|
||||
leakage_powers_ = new LeakagePowerSeq;
|
||||
leakage_powers_->push_back(power);
|
||||
leakage_powers_.push_back(power);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1155,12 +1089,10 @@ LibertyCell::finish(bool infer_latches,
|
|||
Debug *debug)
|
||||
{
|
||||
translatePresetClrCheckRoles();
|
||||
if (timing_arc_sets_) {
|
||||
makeTimingArcMap(report);
|
||||
makeTimingArcPortMaps();
|
||||
findDefaultCondArcs();
|
||||
makeLatchEnables(report, debug);
|
||||
}
|
||||
makeTimingArcMap(report);
|
||||
makeTimingArcPortMaps();
|
||||
findDefaultCondArcs();
|
||||
makeLatchEnables(report, debug);
|
||||
if (infer_latches
|
||||
&& !interface_timing_)
|
||||
inferLatchRoles(debug);
|
||||
|
|
@ -1169,24 +1101,17 @@ LibertyCell::finish(bool infer_latches,
|
|||
void
|
||||
LibertyCell::findDefaultCondArcs()
|
||||
{
|
||||
LibertyPortPairTimingArcMap::Iterator set_iter1(port_timing_arc_set_map_);
|
||||
while (set_iter1.hasNext()) {
|
||||
LibertyPortPair *port_pair;
|
||||
TimingArcSetSeq *sets;
|
||||
set_iter1.next(port_pair, sets);
|
||||
for (auto port_pair_set : port_timing_arc_set_map_) {
|
||||
TimingArcSetSeq *sets = port_pair_set.second;
|
||||
bool has_cond_arcs = false;
|
||||
TimingArcSetSeq::Iterator set_iter2(sets);
|
||||
while (set_iter2.hasNext()) {
|
||||
TimingArcSet *set = set_iter2.next();
|
||||
for (auto set : *sets) {
|
||||
if (set->cond()) {
|
||||
has_cond_arcs = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (has_cond_arcs) {
|
||||
TimingArcSetSeq::Iterator set_iter3(sets);
|
||||
while (set_iter3.hasNext()) {
|
||||
TimingArcSet *set = set_iter3.next();
|
||||
for (auto set : *sets) {
|
||||
if (!set->cond())
|
||||
set->setIsCondDefault(true);
|
||||
}
|
||||
|
|
@ -1201,22 +1126,18 @@ void
|
|||
LibertyCell::translatePresetClrCheckRoles()
|
||||
{
|
||||
LibertyPortSet pre_clr_ports;
|
||||
LibertyCellTimingArcSetIterator set_iter(this);
|
||||
while (set_iter.hasNext()) {
|
||||
TimingArcSet *set = set_iter.next();
|
||||
if (set->role() == TimingRole::regSetClr())
|
||||
pre_clr_ports.insert(set->from());
|
||||
for (auto arc_set : timing_arc_sets_) {
|
||||
if (arc_set->role() == TimingRole::regSetClr())
|
||||
pre_clr_ports.insert(arc_set->from());
|
||||
}
|
||||
|
||||
if (!pre_clr_ports.empty()) {
|
||||
LibertyCellTimingArcSetIterator set_iter(this);
|
||||
while (set_iter.hasNext()) {
|
||||
TimingArcSet *set = set_iter.next();
|
||||
if (pre_clr_ports.findKey(set->to())) {
|
||||
if (set->role() == TimingRole::setup())
|
||||
set->setRole(TimingRole::recovery());
|
||||
else if (set->role() == TimingRole::hold())
|
||||
set->setRole(TimingRole::removal());
|
||||
for (auto arc_set : timing_arc_sets_) {
|
||||
if (pre_clr_ports.findKey(arc_set->to())) {
|
||||
if (arc_set->role() == TimingRole::setup())
|
||||
arc_set->setRole(TimingRole::recovery());
|
||||
else if (arc_set->role() == TimingRole::hold())
|
||||
arc_set->setRole(TimingRole::removal());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1225,17 +1146,16 @@ LibertyCell::translatePresetClrCheckRoles()
|
|||
void
|
||||
LibertyCell::makeTimingArcMap(Report *)
|
||||
{
|
||||
timing_arc_set_map_ = new TimingArcSetMap;
|
||||
// Filter duplicate timing arcs, keeping the later definition.
|
||||
for (auto arc_set : *timing_arc_sets_)
|
||||
for (auto arc_set : timing_arc_sets_)
|
||||
// The last definition will be left in the set.
|
||||
timing_arc_set_map_->insert(arc_set);
|
||||
timing_arc_set_map_.insert(arc_set);
|
||||
|
||||
// Prune the arc sets not in the map.
|
||||
int j = 0;
|
||||
for (int i = 0; i < timing_arc_sets_->size(); i++) {
|
||||
TimingArcSet *arc_set = (*timing_arc_sets_)[i];
|
||||
TimingArcSet *match = timing_arc_set_map_->findKey(arc_set);
|
||||
for (int i = 0; i < timing_arc_sets_.size(); i++) {
|
||||
TimingArcSet *arc_set = timing_arc_sets_[i];
|
||||
TimingArcSet *match = timing_arc_set_map_.findKey(arc_set);
|
||||
if (match != arc_set) {
|
||||
// Unfortunately these errors are common in some brain damaged
|
||||
// libraries.
|
||||
|
|
@ -1248,45 +1168,40 @@ LibertyCell::makeTimingArcMap(Report *)
|
|||
}
|
||||
else
|
||||
// Shift arc sets down to fill holes left by removed duplicates.
|
||||
(*timing_arc_sets_)[j++] = arc_set;
|
||||
timing_arc_sets_[j++] = arc_set;
|
||||
}
|
||||
timing_arc_sets_->resize(j);
|
||||
timing_arc_sets_.resize(j);
|
||||
|
||||
if (timing_arc_set_map_->size() != timing_arc_sets_->size())
|
||||
if (timing_arc_set_map_.size() != timing_arc_sets_.size())
|
||||
internalError("timing arc count mismatch\n");
|
||||
}
|
||||
|
||||
void
|
||||
LibertyCell::makeTimingArcPortMaps()
|
||||
{
|
||||
port_timing_arc_set_map_ = new LibertyPortPairTimingArcMap;
|
||||
timing_arc_set_from_map_ = new LibertyPortTimingArcMap;
|
||||
timing_arc_set_to_map_ = new LibertyPortTimingArcMap;
|
||||
|
||||
for (auto arc_set : *timing_arc_sets_) {
|
||||
for (auto arc_set : timing_arc_sets_) {
|
||||
LibertyPort *from = arc_set->from();
|
||||
LibertyPort *to = arc_set->to();
|
||||
LibertyPortPair port_pair(from, to);
|
||||
TimingArcSetSeq *sets = port_timing_arc_set_map_->findKey(&port_pair);
|
||||
TimingArcSetSeq *sets = port_timing_arc_set_map_.findKey(port_pair);
|
||||
if (sets == nullptr) {
|
||||
// First arc set for from/to ports.
|
||||
sets = new TimingArcSetSeq;
|
||||
LibertyPortPair *port_pair1 = new LibertyPortPair(from, to);
|
||||
(*port_timing_arc_set_map_)[port_pair1] = sets;
|
||||
port_timing_arc_set_map_[port_pair] = sets;
|
||||
}
|
||||
sets->push_back(arc_set);
|
||||
|
||||
sets = timing_arc_set_from_map_->findKey(from);
|
||||
sets = timing_arc_set_from_map_.findKey(from);
|
||||
if (sets == nullptr) {
|
||||
sets = new TimingArcSetSeq;
|
||||
(*timing_arc_set_from_map_)[from] = sets;
|
||||
timing_arc_set_from_map_[from] = sets;
|
||||
}
|
||||
sets->push_back(arc_set);
|
||||
|
||||
sets = timing_arc_set_to_map_->findKey(to);
|
||||
sets = timing_arc_set_to_map_.findKey(to);
|
||||
if (sets == nullptr) {
|
||||
sets = new TimingArcSetSeq;
|
||||
(*timing_arc_set_to_map_)[to] = sets;
|
||||
timing_arc_set_to_map_[to] = sets;
|
||||
}
|
||||
sets->push_back(arc_set);
|
||||
}
|
||||
|
|
@ -1296,49 +1211,41 @@ TimingArcSetSeq *
|
|||
LibertyCell::timingArcSets(const LibertyPort *from,
|
||||
const LibertyPort *to) const
|
||||
{
|
||||
if (timing_arc_sets_) {
|
||||
if (from && to) {
|
||||
LibertyPortPair port_pair(from, to);
|
||||
return port_timing_arc_set_map_->findKey(&port_pair);
|
||||
}
|
||||
else if (from)
|
||||
return timing_arc_set_from_map_->findKey(from);
|
||||
else if (to)
|
||||
return timing_arc_set_to_map_->findKey(to);
|
||||
if (from && to) {
|
||||
LibertyPortPair port_pair(from, to);
|
||||
return port_timing_arc_set_map_.findKey(port_pair);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TimingArcSet *
|
||||
LibertyCell::findTimingArcSet(TimingArcSet *key) const
|
||||
{
|
||||
if (timing_arc_sets_)
|
||||
return timing_arc_set_map_->findKey(key);
|
||||
else if (from)
|
||||
return timing_arc_set_from_map_.findKey(from);
|
||||
else if (to)
|
||||
return timing_arc_set_to_map_.findKey(to);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TimingArcSet *
|
||||
LibertyCell::findTimingArcSet(TimingArcSet *key) const
|
||||
{
|
||||
return timing_arc_set_map_.findKey(key);
|
||||
}
|
||||
|
||||
TimingArcSet *
|
||||
LibertyCell::findTimingArcSet(unsigned arc_set_index) const
|
||||
{
|
||||
return (*timing_arc_sets_)[arc_set_index];
|
||||
return timing_arc_sets_[arc_set_index];
|
||||
}
|
||||
|
||||
size_t
|
||||
LibertyCell::timingArcSetCount() const
|
||||
{
|
||||
if (timing_arc_sets_)
|
||||
return timing_arc_sets_->size();
|
||||
else
|
||||
return 0;
|
||||
return timing_arc_sets_.size();
|
||||
}
|
||||
|
||||
bool
|
||||
LibertyCell::hasTimingArcs(LibertyPort *port) const
|
||||
{
|
||||
return timing_arc_sets_
|
||||
&& (timing_arc_set_from_map_->findKey(port)
|
||||
|| timing_arc_set_to_map_->findKey(port));
|
||||
return timing_arc_set_from_map_.findKey(port)
|
||||
|| timing_arc_set_to_map_.findKey(port);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1376,38 +1283,29 @@ LibertyCell::makeSequential(int size,
|
|||
clear_bit,preset_bit,
|
||||
clr_preset_out, clr_preset_out_inv,
|
||||
out_bit, out_inv_bit);
|
||||
if (sequentials_ == nullptr) {
|
||||
sequentials_ = new SequentialSeq;
|
||||
port_to_seq_map_ = new PortToSequentialMap;
|
||||
}
|
||||
sequentials_->push_back(seq);
|
||||
(*port_to_seq_map_)[seq->output()] = seq;
|
||||
(*port_to_seq_map_)[seq->outputInv()] = seq;
|
||||
sequentials_.push_back(seq);
|
||||
port_to_seq_map_[seq->output()] = seq;
|
||||
port_to_seq_map_[seq->outputInv()] = seq;
|
||||
}
|
||||
}
|
||||
|
||||
Sequential *
|
||||
LibertyCell::outputPortSequential(LibertyPort *port)
|
||||
{
|
||||
if (port_to_seq_map_)
|
||||
return port_to_seq_map_->findKey(port);
|
||||
else
|
||||
return nullptr;
|
||||
return port_to_seq_map_.findKey(port);
|
||||
}
|
||||
|
||||
bool
|
||||
LibertyCell::hasSequentials() const
|
||||
{
|
||||
return sequentials_ && !sequentials_->empty();
|
||||
return !sequentials_.empty();
|
||||
}
|
||||
|
||||
void
|
||||
LibertyCell::addScaledCell(OperatingConditions *op_cond,
|
||||
LibertyCell *scaled_cell)
|
||||
{
|
||||
if (scaled_cells_ == nullptr)
|
||||
scaled_cells_ = new ScaledCellMap;
|
||||
(*scaled_cells_)[op_cond] = scaled_cell;
|
||||
scaled_cells_[op_cond] = scaled_cell;
|
||||
|
||||
LibertyCellPortBitIterator port_iter1(this);
|
||||
LibertyCellPortBitIterator port_iter2(scaled_cell);
|
||||
|
|
@ -1523,14 +1421,14 @@ LibertyCell::addOcvDerate(OcvDerate *derate)
|
|||
////////////////////////////////////////////////////////////////
|
||||
|
||||
LibertyCellTimingArcSetIterator::LibertyCellTimingArcSetIterator(const LibertyCell *cell) :
|
||||
TimingArcSetSeq::Iterator(cell->timing_arc_sets_)
|
||||
TimingArcSetSeq::ConstIterator(&cell->timing_arc_sets_)
|
||||
{
|
||||
}
|
||||
|
||||
LibertyCellTimingArcSetIterator::LibertyCellTimingArcSetIterator(const LibertyCell *cell,
|
||||
const LibertyPort *from,
|
||||
const LibertyPort *to):
|
||||
TimingArcSetSeq::Iterator(cell->timingArcSets(from, to))
|
||||
TimingArcSetSeq::ConstIterator(cell->timingArcSets(from, to))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -1598,9 +1496,7 @@ LibertyCell::makeLatchEnables(Report *report,
|
|||
{
|
||||
if (hasSequentials()
|
||||
|| hasInferedRegTimingArcs()) {
|
||||
LibertyCellTimingArcSetIterator set_iter(this);
|
||||
while (set_iter.hasNext()) {
|
||||
TimingArcSet *en_to_q = set_iter.next();
|
||||
for (auto en_to_q : timing_arc_sets_) {
|
||||
if (en_to_q->role() == TimingRole::latchEnToQ()) {
|
||||
LibertyPort *en = en_to_q->from();
|
||||
LibertyPort *q = en_to_q->to();
|
||||
|
|
@ -1617,7 +1513,7 @@ LibertyCell::makeLatchEnables(Report *report,
|
|||
en_to_q,
|
||||
setup_check,
|
||||
debug);
|
||||
TimingArcSetArcIterator check_arc_iter( setup_check);
|
||||
TimingArcSetArcIterator check_arc_iter(setup_check);
|
||||
if (check_arc_iter.hasNext()) {
|
||||
TimingArc *check_arc = check_arc_iter.next();
|
||||
TransRiseFall *en_tr = latch_enable->enableTransition();
|
||||
|
|
@ -1668,9 +1564,7 @@ FuncExpr *
|
|||
LibertyCell::findLatchEnableFunc(LibertyPort *data,
|
||||
LibertyPort *enable) const
|
||||
{
|
||||
LibertyCellSequentialIterator iter(this);
|
||||
while (iter.hasNext()) {
|
||||
Sequential *seq = iter.next();
|
||||
for (auto seq : sequentials_) {
|
||||
if (seq->isLatch()
|
||||
&& seq->data()
|
||||
&& seq->data()->hasPort(data)
|
||||
|
|
@ -2264,6 +2158,15 @@ LibertyPortPairLess::operator()(const LibertyPortPair *pair1,
|
|||
&& pair1->second < pair2->second);
|
||||
}
|
||||
|
||||
bool
|
||||
LibertyPortPairLess::operator()(const LibertyPortPair &pair1,
|
||||
const LibertyPortPair &pair2) const
|
||||
{
|
||||
return pair1.first < pair2.first
|
||||
|| (pair1.first == pair2.first
|
||||
&& pair1.second < pair2.second);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
LibertyPortMemberIterator::LibertyPortMemberIterator(const LibertyPort *port) :
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ typedef Map<const char*, OperatingConditions*,
|
|||
typedef Map<LibertyPort*, Sequential*> PortToSequentialMap;
|
||||
typedef Vector<TimingArcSet*> TimingArcSetSeq;
|
||||
typedef Set<TimingArcSet*, TimingArcSetLess> TimingArcSetMap;
|
||||
typedef Map<LibertyPortPair*, TimingArcSetSeq*,
|
||||
typedef Map<LibertyPortPair, TimingArcSetSeq*,
|
||||
LibertyPortPairLess> LibertyPortPairTimingArcMap;
|
||||
typedef Vector<InternalPower*> InternalPowerSeq;
|
||||
typedef Vector<LeakagePower*> LeakagePowerSeq;
|
||||
|
|
@ -427,8 +427,8 @@ public:
|
|||
TimingArcSet *findTimingArcSet(TimingArcSet *key) const;
|
||||
TimingArcSet *findTimingArcSet(unsigned arc_set_index) const;
|
||||
bool hasTimingArcs(LibertyPort *port) const;
|
||||
InternalPowerSeq *internalPowers() const { return internal_powers_; }
|
||||
LeakagePowerSeq *leakagePowers() const { return leakage_powers_; }
|
||||
InternalPowerSeq *internalPowers() { return &internal_powers_; }
|
||||
LeakagePowerSeq *leakagePowers() { return &leakage_powers_; }
|
||||
float leakagePower() const { return leakage_power_; }
|
||||
bool hasSequentials() const;
|
||||
void makeSequential(int size,
|
||||
|
|
@ -507,23 +507,23 @@ protected:
|
|||
bool has_internal_ports_;
|
||||
bool interface_timing_;
|
||||
ClockGateType clock_gate_type_;
|
||||
TimingArcSetSeq *timing_arc_sets_;
|
||||
TimingArcSetSeq timing_arc_sets_;
|
||||
// Used to find matching arc sets in equivalent cells.
|
||||
TimingArcSetMap *timing_arc_set_map_;
|
||||
LibertyPortPairTimingArcMap *port_timing_arc_set_map_;
|
||||
LibertyPortTimingArcMap *timing_arc_set_from_map_;
|
||||
LibertyPortTimingArcMap *timing_arc_set_to_map_;
|
||||
TimingArcSetMap timing_arc_set_map_;
|
||||
LibertyPortPairTimingArcMap port_timing_arc_set_map_;
|
||||
LibertyPortTimingArcMap timing_arc_set_from_map_;
|
||||
LibertyPortTimingArcMap timing_arc_set_to_map_;
|
||||
TimingArcAttrsSeq timing_arc_attrs_;
|
||||
bool has_infered_reg_timing_arcs_;
|
||||
InternalPowerSeq *internal_powers_;
|
||||
InternalPowerSeq internal_powers_;
|
||||
InternalPowerAttrsSeq internal_power_attrs_;
|
||||
LeakagePowerSeq *leakage_powers_;
|
||||
SequentialSeq *sequentials_;
|
||||
PortToSequentialMap *port_to_seq_map_;
|
||||
LeakagePowerSeq leakage_powers_;
|
||||
SequentialSeq sequentials_;
|
||||
PortToSequentialMap port_to_seq_map_;
|
||||
BusDclMap bus_dcls_;
|
||||
ModeDefMap *mode_defs_;
|
||||
ModeDefMap mode_defs_;
|
||||
ScaleFactors *scale_factors_;
|
||||
ScaledCellMap *scaled_cells_;
|
||||
ScaledCellMap scaled_cells_;
|
||||
TestCell *test_cell_;
|
||||
// Latch D->Q to LatchEnable.
|
||||
LatchEnableMap latch_d_to_q_map_;
|
||||
|
|
@ -577,7 +577,7 @@ private:
|
|||
ConcreteCellPortBitIterator *iter_;
|
||||
};
|
||||
|
||||
class LibertyCellTimingArcSetIterator : public TimingArcSetSeq::Iterator
|
||||
class LibertyCellTimingArcSetIterator : public TimingArcSetSeq::ConstIterator
|
||||
{
|
||||
public:
|
||||
LibertyCellTimingArcSetIterator(const LibertyCell *cell);
|
||||
|
|
@ -596,14 +596,14 @@ public:
|
|||
class LibertyCellLeakagePowerIterator : public LeakagePowerSeq::Iterator
|
||||
{
|
||||
public:
|
||||
LibertyCellLeakagePowerIterator(const LibertyCell *cell) :
|
||||
LibertyCellLeakagePowerIterator(LibertyCell *cell) :
|
||||
LeakagePowerSeq::Iterator(cell->leakagePowers()) {}
|
||||
};
|
||||
|
||||
class LibertyCellInternalPowerIterator : public InternalPowerSeq::Iterator
|
||||
{
|
||||
public:
|
||||
LibertyCellInternalPowerIterator(const LibertyCell *cell) :
|
||||
LibertyCellInternalPowerIterator(LibertyCell *cell) :
|
||||
InternalPowerSeq::Iterator(cell->internalPowers()) {}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -148,6 +148,8 @@ class LibertyPortPairLess
|
|||
public:
|
||||
bool operator()(const LibertyPortPair *pair1,
|
||||
const LibertyPortPair *pair2) const;
|
||||
bool operator()(const LibertyPortPair &pair1,
|
||||
const LibertyPortPair &pair2) const;
|
||||
};
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -4345,6 +4345,8 @@ LibertyReader::getAttrEarlyLate(LibertyAttr *attr)
|
|||
return EarlyLateAll::min();
|
||||
else if (stringEq(value, "late"))
|
||||
return EarlyLateAll::max();
|
||||
else if (stringEq(value, "early_and_late"))
|
||||
return EarlyLateAll::all();
|
||||
else {
|
||||
libWarn(attr, "unknown early/late value.\n");
|
||||
return EarlyLateAll::all();
|
||||
|
|
|
|||
Loading…
Reference in New Issue