liberty memory management
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
c7f4bb3bb3
commit
33e480a6c1
|
|
@ -65,11 +65,11 @@ ArcDcalcWaveforms::inputWaveform(ArcDcalcArg &dcalc_arg,
|
|||
report->error(1751, "VDD not defined in library %s", library->name());
|
||||
Waveform in_waveform = driver_waveform->waveform(delayAsFloat(in_slew));
|
||||
// Delay time axis.
|
||||
FloatSeq *time_values = new FloatSeq;
|
||||
for (float time : *in_waveform.axis1()->values())
|
||||
time_values->push_back(time + dcalc_arg.inputDelay());
|
||||
FloatSeq time_values;
|
||||
for (float time : in_waveform.axis1()->values())
|
||||
time_values.push_back(time + dcalc_arg.inputDelay());
|
||||
TableAxisPtr time_axis = make_shared<TableAxis>(TableAxisVariable::time,
|
||||
time_values);
|
||||
std::move(time_values));
|
||||
// Scale the waveform from 0:vdd.
|
||||
FloatSeq *scaled_values = new FloatSeq;
|
||||
for (float value : *in_waveform.values()) {
|
||||
|
|
|
|||
|
|
@ -530,12 +530,13 @@ CcsCeffDelayCalc::drvrWaveform()
|
|||
}
|
||||
}
|
||||
TableAxisPtr drvr_time_axis = make_shared<TableAxis>(TableAxisVariable::time,
|
||||
drvr_times);
|
||||
Table1 drvr_table(drvr_volts, drvr_time_axis);
|
||||
std::move(*drvr_times));
|
||||
delete drvr_times;
|
||||
Table drvr_table(drvr_volts, drvr_time_axis);
|
||||
return drvr_table;
|
||||
}
|
||||
else
|
||||
return Table1();
|
||||
return Table();
|
||||
}
|
||||
|
||||
Waveform
|
||||
|
|
@ -561,12 +562,13 @@ CcsCeffDelayCalc::loadWaveform(const Pin *load_pin)
|
|||
load_volts->push_back(v1);
|
||||
}
|
||||
TableAxisPtr load_time_axis = make_shared<TableAxis>(TableAxisVariable::time,
|
||||
load_times);
|
||||
Table1 load_table(load_volts, load_time_axis);
|
||||
std::move(*load_times));
|
||||
delete load_times;
|
||||
Table load_table(load_volts, load_time_axis);
|
||||
return load_table;
|
||||
}
|
||||
}
|
||||
return Table1();
|
||||
return Table();
|
||||
}
|
||||
|
||||
Waveform
|
||||
|
|
@ -605,12 +607,13 @@ CcsCeffDelayCalc::drvrRampWaveform(const Pin *in_pin,
|
|||
load_volts->push_back(v1);
|
||||
}
|
||||
TableAxisPtr load_time_axis = make_shared<TableAxis>(TableAxisVariable::time,
|
||||
load_times);
|
||||
Table1 load_table(load_volts, load_time_axis);
|
||||
std::move(*load_times));
|
||||
delete load_times;
|
||||
Table load_table(load_volts, load_time_axis);
|
||||
return load_table;
|
||||
}
|
||||
}
|
||||
return Table1();
|
||||
return Table();
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -564,7 +564,7 @@ GraphDelayCalc::driveCellDefaultFromPort(const LibertyCell *cell,
|
|||
{
|
||||
LibertyPort *from_port = 0;
|
||||
int from_port_index = 0;
|
||||
for (TimingArcSet *arc_set : cell->timingArcSets(nullptr, to_port)) {
|
||||
for (TimingArcSet *arc_set : cell->timingArcSetsTo(to_port)) {
|
||||
LibertyPort *set_from_port = arc_set->from();
|
||||
int set_from_port_index = findPortIndex(cell, set_from_port);
|
||||
if (from_port == nullptr
|
||||
|
|
|
|||
|
|
@ -960,8 +960,8 @@ PrimaDelayCalc::watchWaveform(const Pin *pin)
|
|||
{
|
||||
FloatSeq &voltages = watch_pin_values_[pin];
|
||||
TableAxisPtr time_axis = make_shared<TableAxis>(TableAxisVariable::time,
|
||||
new FloatSeq(times_));
|
||||
Table1 waveform(new FloatSeq(voltages), time_axis);
|
||||
FloatSeq(times_));
|
||||
Table waveform(new FloatSeq(voltages), time_axis);
|
||||
return waveform;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ using MatrixSd = Eigen::SparseMatrix<double>;
|
|||
using PinLMap = std::map<const Pin*, Eigen::VectorXd, PinIdLess>;
|
||||
using WatchPinValuesMap = std::map<const Pin*, FloatSeq, PinIdLess>;
|
||||
|
||||
using Waveform = Table1;
|
||||
using Waveform = Table;
|
||||
|
||||
ArcDelayCalc *
|
||||
makePrimaDelayCalc(StaState *sta);
|
||||
|
|
|
|||
|
|
@ -271,13 +271,13 @@ cond()
|
|||
const char *
|
||||
mode_name()
|
||||
{
|
||||
return self->timingArcSet()->modeName();
|
||||
return self->timingArcSet()->modeName().c_str();
|
||||
}
|
||||
|
||||
const char *
|
||||
mode_value()
|
||||
{
|
||||
return self->timingArcSet()->modeValue();
|
||||
return self->timingArcSet()->modeValue().c_str();
|
||||
}
|
||||
|
||||
const char *
|
||||
|
|
|
|||
|
|
@ -143,8 +143,8 @@ struct find_return<C, false>
|
|||
};
|
||||
|
||||
|
||||
// Find an value in a contaiiner of pointers.
|
||||
// return nullptr if not found.
|
||||
// Find an pointer value in a reference to a contaiiner of pointers.
|
||||
// Return nullptr if not found.
|
||||
template<typename AssocContainer>
|
||||
auto
|
||||
findKey(const AssocContainer& c,
|
||||
|
|
@ -166,11 +166,11 @@ findKey(const AssocContainer& c,
|
|||
return *it; // set
|
||||
}
|
||||
|
||||
// Find an value in a contaiiner of pointers.
|
||||
// return nullptr if not found.
|
||||
// Find an pointer value in a pointer to a contaiiner of pointers.
|
||||
// Return nullptr if not found.
|
||||
template<typename AssocContainer>
|
||||
auto
|
||||
findKey(const AssocContainer* c,
|
||||
findKey(const AssocContainer *c,
|
||||
typename AssocContainer::key_type key)
|
||||
-> typename find_return<AssocContainer>::type
|
||||
{
|
||||
|
|
@ -191,6 +191,29 @@ findKey(const AssocContainer* c,
|
|||
return *it;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Find a value reference in a container. Returns reference to the value if found,
|
||||
// otherwise returns reference to a static empty value of the same type.
|
||||
template<typename AssocContainer>
|
||||
auto
|
||||
findKeyValue(const AssocContainer& c,
|
||||
typename AssocContainer::key_type key)
|
||||
-> const typename find_return<AssocContainer>::type &
|
||||
{
|
||||
auto it = c.find(key);
|
||||
if (it != c.end()) {
|
||||
if constexpr (has_mapped_type<AssocContainer>::value)
|
||||
return it->second;
|
||||
else
|
||||
return *it;
|
||||
}
|
||||
static const typename find_return<AssocContainer>::type empty{};
|
||||
return empty;
|
||||
}
|
||||
|
||||
// Find an value reference in a reference to a contaiiner of objects.
|
||||
// Return exists.
|
||||
template<typename AssocContainer>
|
||||
void
|
||||
findKeyValue(const AssocContainer& c,
|
||||
|
|
@ -205,7 +228,7 @@ findKeyValue(const AssocContainer& c,
|
|||
}
|
||||
|
||||
if constexpr (has_mapped_type<AssocContainer>::value) {
|
||||
// map
|
||||
// map
|
||||
value = it->second;
|
||||
exists = true;
|
||||
}
|
||||
|
|
@ -216,6 +239,8 @@ findKeyValue(const AssocContainer& c,
|
|||
}
|
||||
}
|
||||
|
||||
// Find an value reference in a pointer to a contaiiner of objects.
|
||||
// Return exists.
|
||||
template<typename AssocContainer>
|
||||
void
|
||||
findKeyValue(const AssocContainer *c,
|
||||
|
|
@ -241,6 +266,9 @@ findKeyValue(const AssocContainer *c,
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Find an value pointer in a reference to a contaiiner of objects.
|
||||
template<typename AssocContainer>
|
||||
auto
|
||||
findKeyValuePtr(AssocContainer& c,
|
||||
|
|
@ -252,7 +280,27 @@ findKeyValuePtr(AssocContainer& c,
|
|||
return nullptr;
|
||||
|
||||
if constexpr (has_mapped_type<AssocContainer>::value)
|
||||
// map
|
||||
// map
|
||||
return &it->second;
|
||||
else
|
||||
// set
|
||||
return *it;
|
||||
}
|
||||
|
||||
// Find an pointger to a value in a const reference to a contaiiner objects.
|
||||
// Return nullptr if not found.
|
||||
template<typename AssocContainer>
|
||||
auto
|
||||
findKeyValuePtr(const AssocContainer& c,
|
||||
typename AssocContainer::key_type key)
|
||||
-> const typename find_return<AssocContainer>::type*
|
||||
{
|
||||
auto it = c.find(key);
|
||||
if (it == c.end())
|
||||
return nullptr;
|
||||
|
||||
if constexpr (has_mapped_type<AssocContainer>::value)
|
||||
// map
|
||||
return &it->second;
|
||||
else
|
||||
// set
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ public:
|
|||
FuncExpr *left,
|
||||
FuncExpr *right,
|
||||
LibertyPort *port);
|
||||
~FuncExpr();
|
||||
void shallowDelete();
|
||||
static FuncExpr *makePort(LibertyPort *port);
|
||||
static FuncExpr *makeNot(FuncExpr *expr);
|
||||
static FuncExpr *makeAnd(FuncExpr *left,
|
||||
|
|
@ -61,11 +63,11 @@ public:
|
|||
const FuncExpr *expr2);
|
||||
static bool less(const FuncExpr *expr1,
|
||||
const FuncExpr *expr2);
|
||||
// Invert expr by deleting leading NOT if found.
|
||||
FuncExpr *invert();
|
||||
|
||||
// Deep copy.
|
||||
FuncExpr *copy();
|
||||
// Delete expression and all of its subexpressions.
|
||||
void deleteSubexprs();
|
||||
// op == port
|
||||
LibertyPort *port() const;
|
||||
Op op() const { return op_; }
|
||||
|
|
|
|||
|
|
@ -24,58 +24,46 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "LibertyClass.hh"
|
||||
#include "Transition.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
class InternalPowerAttrs;
|
||||
class InternalPowerModel;
|
||||
|
||||
class InternalPowerAttrs
|
||||
{
|
||||
public:
|
||||
InternalPowerAttrs();
|
||||
virtual ~InternalPowerAttrs();
|
||||
void deleteContents();
|
||||
FuncExpr *when() const { return when_; }
|
||||
void setWhen(FuncExpr *when);
|
||||
void setModel(const RiseFall *rf,
|
||||
InternalPowerModel *model);
|
||||
InternalPowerModel *model(const RiseFall *rf) const;
|
||||
const char *relatedPgPin() const { return related_pg_pin_; }
|
||||
void setRelatedPgPin(const char *related_pg_pin);
|
||||
|
||||
protected:
|
||||
FuncExpr *when_;
|
||||
InternalPowerModel *models_[RiseFall::index_count];
|
||||
const char *related_pg_pin_;
|
||||
};
|
||||
using InternalPowerModels =
|
||||
std::array<std::shared_ptr<InternalPowerModel>, RiseFall::index_count>;
|
||||
|
||||
class InternalPower
|
||||
{
|
||||
public:
|
||||
InternalPower(LibertyCell *cell,
|
||||
LibertyPort *port,
|
||||
InternalPower(LibertyPort *port,
|
||||
LibertyPort *related_port,
|
||||
InternalPowerAttrs *attrs);
|
||||
~InternalPower();
|
||||
const std::string &related_pg_pin,
|
||||
const std::shared_ptr<FuncExpr> &when,
|
||||
InternalPowerModels &models);
|
||||
//InternalPower(InternalPower &&other) noexcept;
|
||||
LibertyCell *libertyCell() const;
|
||||
LibertyPort *port() const { return port_; }
|
||||
LibertyPort *relatedPort() const { return related_port_; }
|
||||
FuncExpr *when() const { return when_; }
|
||||
const char *relatedPgPin() const { return related_pg_pin_; }
|
||||
FuncExpr *when() const { return when_.get(); }
|
||||
const std::string &relatedPgPin() const { return related_pg_pin_; }
|
||||
float power(const RiseFall *rf,
|
||||
const Pvt *pvt,
|
||||
float in_slew,
|
||||
float load_cap);
|
||||
float load_cap) const;
|
||||
const InternalPowerModel *model(const RiseFall *rf) const;
|
||||
|
||||
protected:
|
||||
LibertyPort *port_;
|
||||
LibertyPort *related_port_;
|
||||
FuncExpr *when_;
|
||||
const char *related_pg_pin_;
|
||||
InternalPowerModel *models_[RiseFall::index_count];
|
||||
std::string related_pg_pin_;
|
||||
std::shared_ptr<FuncExpr> when_;
|
||||
InternalPowerModels models_;
|
||||
};
|
||||
|
||||
class InternalPowerModel
|
||||
|
|
@ -92,6 +80,7 @@ public:
|
|||
float in_slew,
|
||||
float load_cap,
|
||||
int digits) const;
|
||||
const TableModel *model() const { return model_; }
|
||||
|
||||
protected:
|
||||
void findAxisValues(float in_slew,
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ public:
|
|||
LibertyPort *related_pg_port,
|
||||
FuncExpr *when,
|
||||
float power);
|
||||
LeakagePower(LeakagePower &&other) noexcept;
|
||||
~LeakagePower();
|
||||
LibertyCell *libertyCell() const { return cell_; }
|
||||
LibertyPort *relatedPgPort() const { return related_pg_port_; }
|
||||
|
|
|
|||
|
|
@ -24,11 +24,13 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "ContainerHelpers.hh"
|
||||
|
|
@ -39,6 +41,8 @@
|
|||
#include "MinMaxValues.hh"
|
||||
#include "Transition.hh"
|
||||
#include "Delay.hh"
|
||||
#include "InternalPower.hh"
|
||||
#include "LeakagePower.hh"
|
||||
#include "LibertyClass.hh"
|
||||
|
||||
namespace sta {
|
||||
|
|
@ -48,48 +52,96 @@ class LibertyCellIterator;
|
|||
class LibertyCellPortIterator;
|
||||
class LibertyCellPortBitIterator;
|
||||
class LibertyPortMemberIterator;
|
||||
class ModeValueDef;
|
||||
class TestCell;
|
||||
class PatternMatch;
|
||||
class LatchEnable;
|
||||
class Report;
|
||||
class Debug;
|
||||
class LibertyBuilder;
|
||||
class LibertyReader;
|
||||
class OcvDerate;
|
||||
class TimingArcAttrs;
|
||||
class InternalPowerAttrs;
|
||||
class StaState;
|
||||
class Scene;
|
||||
class DriverWaveform;
|
||||
|
||||
using TableTemplateMap = std::map<const char*, TableTemplate*, CharPtrLess>;
|
||||
// Mode definition mode_value group (defined before ModeValueMap / ModeDef).
|
||||
class ModeValueDef
|
||||
{
|
||||
public:
|
||||
ModeValueDef(std::string value, FuncExpr *cond, std::string sdf_cond);
|
||||
ModeValueDef(ModeValueDef &&other) noexcept;
|
||||
~ModeValueDef();
|
||||
const std::string &value() const { return value_; }
|
||||
FuncExpr *cond() const { return cond_; }
|
||||
void setCond(FuncExpr *cond);
|
||||
const std::string &sdfCond() const { return sdf_cond_; }
|
||||
void setSdfCond(std::string sdf_cond);
|
||||
|
||||
private:
|
||||
std::string value_;
|
||||
FuncExpr *cond_;
|
||||
std::string sdf_cond_;
|
||||
};
|
||||
|
||||
// Latch enable port/function for a latch D->Q timing arc set.
|
||||
class LatchEnable
|
||||
{
|
||||
public:
|
||||
LatchEnable(LibertyPort *data,
|
||||
LibertyPort *enable,
|
||||
const RiseFall *enable_edge,
|
||||
FuncExpr *enable_func,
|
||||
LibertyPort *output,
|
||||
TimingArcSet *d_to_q,
|
||||
TimingArcSet *en_to_q,
|
||||
TimingArcSet *setup_check);
|
||||
LibertyPort *data() const { return data_; }
|
||||
LibertyPort *output() const { return output_; }
|
||||
LibertyPort *enable() const { return enable_; }
|
||||
FuncExpr *enableFunc() const { return enable_func_; }
|
||||
const RiseFall *enableEdge() const { return enable_edge_; }
|
||||
TimingArcSet *dToQ() const { return d_to_q_; }
|
||||
TimingArcSet *enToQ() const { return en_to_q_; }
|
||||
TimingArcSet *setupCheck() const { return setup_check_; }
|
||||
|
||||
private:
|
||||
LibertyPort *data_;
|
||||
LibertyPort *enable_;
|
||||
const RiseFall *enable_edge_;
|
||||
FuncExpr *enable_func_;
|
||||
LibertyPort *output_;
|
||||
TimingArcSet *d_to_q_;
|
||||
TimingArcSet *en_to_q_;
|
||||
TimingArcSet *setup_check_;
|
||||
};
|
||||
|
||||
using TableTemplateMap = std::map<std::string, TableTemplate>;
|
||||
using TableTemplateSeq = std::vector<TableTemplate*>;
|
||||
using BusDclMap = std::map<const char*, BusDcl *, CharPtrLess>;
|
||||
using BusDclSeq = std::vector<BusDcl *>;
|
||||
using ScaleFactorsMap = std::map<const char*, ScaleFactors*, CharPtrLess>;
|
||||
using WireloadMap = std::map<const char*, Wireload*, CharPtrLess>;
|
||||
using WireloadSelectionMap = std::map<const char*, WireloadSelection*, CharPtrLess>;
|
||||
using OperatingConditionsMap = std::map<const char*, OperatingConditions*, CharPtrLess>;
|
||||
using PortToSequentialMap = std::map<LibertyPort*, Sequential*>;
|
||||
using BusDclMap = std::map<std::string, BusDcl>;
|
||||
using BusDclSeq = std::vector<BusDcl*>;
|
||||
using ScaleFactorsMap = std::map<std::string, ScaleFactors>;
|
||||
using WireloadMap = std::map<std::string, Wireload>;
|
||||
using WireloadSelectionMap = std::map<std::string, WireloadSelection>;
|
||||
using OperatingConditionsMap = std::map<std::string, OperatingConditions>;
|
||||
using PortToSequentialMap = std::map<LibertyPort*, size_t>;
|
||||
using TimingArcSetSeq = std::vector<TimingArcSet*>;
|
||||
using TimingArcSetSet = std::set<TimingArcSet*, TimingArcSetLess>;
|
||||
using LibertyPortPairTimingArcMap = std::map<LibertyPortPair, TimingArcSetSeq*,
|
||||
using LibertyPortPairTimingArcMap = std::map<LibertyPortPair, TimingArcSetSeq,
|
||||
LibertyPortPairLess>;
|
||||
using InternalPowerSeq = std::vector<InternalPower*>;
|
||||
using PortInternalPowerMap = std::map<const LibertyPort *, InternalPowerSeq>;
|
||||
using LeakagePowerSeq = std::vector<LeakagePower*>;
|
||||
using LibertyPortTimingArcMap = std::map<const LibertyPort*, TimingArcSetSeq*>;
|
||||
using InternalPowerSeq = std::vector<InternalPower>;
|
||||
using InternalPowerPtrSeq = std::vector<const InternalPower*>;
|
||||
using InternalPowerIndexSeq = std::vector<size_t>;
|
||||
using PortInternalPowerMap = std::map<const LibertyPort *, InternalPowerIndexSeq>;
|
||||
using LeakagePowerSeq = std::vector<LeakagePower>;
|
||||
using ScaledCellMap = std::map<const OperatingConditions*, LibertyCell*>;
|
||||
using ScaledPortMap = std::map<const OperatingConditions*, LibertyPort*>;
|
||||
using ModeDefMap = std::map<const char *, ModeDef*, CharPtrLess>;
|
||||
using ModeValueMap = std::map<const char *, ModeValueDef*, CharPtrLess>;
|
||||
using LatchEnableMap = std::map<const TimingArcSet*, LatchEnable*>;
|
||||
using LatchEnableSeq = std::vector<LatchEnable*>;
|
||||
using OcvDerateMap = std::map<const char *, OcvDerate*, CharPtrLess>;
|
||||
using InternalPowerAttrsSeq = std::vector<InternalPowerAttrs*>;
|
||||
using ModeDefMap = std::map<std::string, ModeDef>;
|
||||
using ModeValueMap = std::map<std::string, ModeValueDef>;
|
||||
using LatchEnableIndexMap = std::map<const TimingArcSet*, size_t>;
|
||||
using LatchEnableSeq = std::vector<LatchEnable>;
|
||||
using OcvDerateMap = std::map<std::string, OcvDerate>;
|
||||
using SupplyVoltageMap = std::map<std::string, float>;
|
||||
using DriverWaveformMap = std::map<std::string, DriverWaveform*>;
|
||||
using DriverWaveformMap = std::map<std::string, DriverWaveform>;
|
||||
using SceneSeq = std::vector<Scene*>;
|
||||
|
||||
enum class ClockGateType { none, latch_posedge, latch_negedge, other };
|
||||
|
|
@ -162,14 +214,15 @@ public:
|
|||
|
||||
DelayModelType delayModelType() const { return delay_model_type_; }
|
||||
void setDelayModelType(DelayModelType type);
|
||||
void addBusDcl(BusDcl *bus_dcl);
|
||||
BusDcl *makeBusDcl(std::string name, int from, int to);
|
||||
BusDcl *findBusDcl(const char *name) const;
|
||||
BusDclSeq busDcls() const;
|
||||
void addTableTemplate(TableTemplate *tbl_template,
|
||||
TableTemplateType type);
|
||||
TableTemplate *makeTableTemplate(std::string name,
|
||||
TableTemplateType type);
|
||||
TableTemplate *findTableTemplate(const char *name,
|
||||
TableTemplateType type);
|
||||
TableTemplateSeq tableTemplates() const;
|
||||
TableTemplateSeq tableTemplates(TableTemplateType type) const;
|
||||
float nominalProcess() const { return nominal_process_; }
|
||||
void setNominalProcess(float process);
|
||||
float nominalVoltage() const { return nominal_voltage_; }
|
||||
|
|
@ -178,8 +231,8 @@ public:
|
|||
void setNominalTemperature(float temperature);
|
||||
|
||||
void setScaleFactors(ScaleFactors *scales);
|
||||
// Add named scale factor group.
|
||||
void addScaleFactors(ScaleFactors *scales);
|
||||
// Make named scale factor group. Returns pointer to the inserted element.
|
||||
ScaleFactors *makeScaleFactors(const char *name);
|
||||
ScaleFactors *findScaleFactors(const char *name);
|
||||
ScaleFactors *scaleFactors() const { return scale_factors_; }
|
||||
float scaleFactor(ScaleFactorType type,
|
||||
|
|
@ -280,20 +333,20 @@ public:
|
|||
Units *units() { return units_; }
|
||||
const Units *units() const { return units_; }
|
||||
|
||||
Wireload *findWireload(const char *name) const;
|
||||
void setDefaultWireload(Wireload *wireload);
|
||||
Wireload *defaultWireload() const;
|
||||
WireloadSelection *findWireloadSelection(const char *name) const;
|
||||
WireloadSelection *defaultWireloadSelection() const;
|
||||
void addWireload(Wireload *wireload);
|
||||
Wireload *makeWireload(std::string name);
|
||||
const Wireload *findWireload(const char *name) const;
|
||||
void setDefaultWireload(const Wireload *wireload);
|
||||
const Wireload *defaultWireload() const;
|
||||
WireloadSelection *makeWireloadSelection(std::string name);
|
||||
const WireloadSelection *findWireloadSelection(const char *name) const;
|
||||
const WireloadSelection *defaultWireloadSelection() const;
|
||||
WireloadMode defaultWireloadMode() const;
|
||||
void setDefaultWireloadMode(WireloadMode mode);
|
||||
void addWireloadSelection(WireloadSelection *selection);
|
||||
void setDefaultWireloadSelection(WireloadSelection *selection);
|
||||
void setDefaultWireloadSelection(const WireloadSelection *selection);
|
||||
|
||||
OperatingConditions *makeOperatingConditions(std::string name);
|
||||
OperatingConditions *findOperatingConditions(const char *name);
|
||||
OperatingConditions *defaultOperatingConditions() const;
|
||||
void addOperatingConditions(OperatingConditions *op_cond);
|
||||
void setDefaultOperatingConditions(OperatingConditions *op_cond);
|
||||
|
||||
// AOCV
|
||||
|
|
@ -302,8 +355,8 @@ public:
|
|||
void setOcvArcDepth(float depth);
|
||||
OcvDerate *defaultOcvDerate() const;
|
||||
void setDefaultOcvDerate(OcvDerate *derate);
|
||||
OcvDerate *makeOcvDerate(std::string name);
|
||||
OcvDerate *findOcvDerate(const char *derate_name);
|
||||
void addOcvDerate(OcvDerate *derate);
|
||||
void addSupplyVoltage(const char *suppy_name,
|
||||
float voltage);
|
||||
bool supplyExists(const char *suppy_name) const;
|
||||
|
|
@ -338,8 +391,9 @@ public:
|
|||
Report *report);
|
||||
|
||||
DriverWaveform *findDriverWaveform(const char *name);
|
||||
DriverWaveform *driverWaveformDefault() { return driver_waveform_default_; }
|
||||
void addDriverWaveform(DriverWaveform *driver_waveform);
|
||||
DriverWaveform *driverWaveformDefault() { return findDriverWaveform(""); }
|
||||
DriverWaveform *makeDriverWaveform(const std::string &name,
|
||||
TablePtr waveforms);
|
||||
|
||||
protected:
|
||||
float degradeWireSlew(const TableModel *model,
|
||||
|
|
@ -376,9 +430,9 @@ protected:
|
|||
float slew_upper_threshold_[RiseFall::index_count];
|
||||
float slew_derate_from_library_;
|
||||
WireloadMap wireloads_;
|
||||
Wireload *default_wire_load_;
|
||||
const Wireload *default_wire_load_;
|
||||
WireloadMode default_wire_load_mode_;
|
||||
WireloadSelection *default_wire_load_selection_;
|
||||
const WireloadSelection *default_wire_load_selection_;
|
||||
WireloadSelectionMap wire_load_selections_;
|
||||
OperatingConditionsMap operating_conditions_;
|
||||
OperatingConditions *default_operating_conditions_;
|
||||
|
|
@ -389,8 +443,6 @@ protected:
|
|||
LibertyCellSeq *buffers_;
|
||||
LibertyCellSeq *inverters_;
|
||||
DriverWaveformMap driver_waveform_map_;
|
||||
// Unnamed driver waveform.
|
||||
DriverWaveform *driver_waveform_default_;
|
||||
|
||||
static constexpr float input_threshold_default_ = .5;
|
||||
static constexpr float output_threshold_default_ = .5;
|
||||
|
|
@ -429,8 +481,8 @@ public:
|
|||
bool hasInternalPorts() const { return has_internal_ports_; }
|
||||
ScaleFactors *scaleFactors() const { return scale_factors_; }
|
||||
void setScaleFactors(ScaleFactors *scale_factors);
|
||||
ModeDef *makeModeDef(const char *name);
|
||||
ModeDef *findModeDef(const char *name);
|
||||
ModeDef *makeModeDef(std::string name);
|
||||
const ModeDef *findModeDef(const char *name) const;
|
||||
|
||||
float area() const { return area_; }
|
||||
void setArea(float area);
|
||||
|
|
@ -462,18 +514,20 @@ public:
|
|||
bool isClockGate() const;
|
||||
void setClockGateType(ClockGateType type);
|
||||
const TimingArcSetSeq &timingArcSets() const { return timing_arc_sets_; }
|
||||
const TimingArcSetSeq &timingArcSetsFrom(const LibertyPort *from) const;
|
||||
const TimingArcSetSeq &timingArcSetsTo(const LibertyPort *to) const;
|
||||
// from or to may be nullptr to wildcard.
|
||||
const TimingArcSetSeq &timingArcSets(const LibertyPort *from,
|
||||
const LibertyPort *to) const;
|
||||
size_t timingArcSetCount() const;
|
||||
// Find a timing arc set equivalent to key.
|
||||
TimingArcSet *findTimingArcSet(TimingArcSet *key) const;
|
||||
TimingArcSet *findTimingArcSet(unsigned arc_set_index) const;
|
||||
TimingArcSet *findTimingArcSet(size_t index) const;
|
||||
bool hasTimingArcs(LibertyPort *port) const;
|
||||
|
||||
const InternalPowerSeq &internalPowers() const { return internal_powers_; }
|
||||
const InternalPowerSeq &internalPowers(const LibertyPort *port);
|
||||
LeakagePowerSeq *leakagePowers() { return &leakage_powers_; }
|
||||
InternalPowerPtrSeq internalPowers(const LibertyPort *port) const;
|
||||
const LeakagePowerSeq &leakagePowers() const { return leakage_powers_; }
|
||||
void leakagePower(// Return values.
|
||||
float &leakage,
|
||||
bool &exists) const;
|
||||
|
|
@ -487,6 +541,7 @@ public:
|
|||
const Statetable *statetable() const { return statetable_; }
|
||||
|
||||
// Find bus declaration local to this cell.
|
||||
BusDcl *makeBusDcl(std::string name, int from, int to);
|
||||
BusDcl *findBusDcl(const char *name) const;
|
||||
// True when TimingArcSetBuilder::makeRegLatchArcs infers register
|
||||
// timing arcs.
|
||||
|
|
@ -505,6 +560,7 @@ public:
|
|||
// AOCV
|
||||
float ocvArcDepth() const;
|
||||
OcvDerate *ocvDerate() const;
|
||||
OcvDerate *makeOcvDerate(std::string name);
|
||||
OcvDerate *findOcvDerate(const char *derate_name);
|
||||
|
||||
// Build helpers.
|
||||
|
|
@ -521,18 +577,25 @@ public:
|
|||
void makeStatetable(LibertyPortSeq &input_ports,
|
||||
LibertyPortSeq &internal_ports,
|
||||
StatetableRows &table);
|
||||
void addBusDcl(BusDcl *bus_dcl);
|
||||
// Add scaled cell after it is complete.
|
||||
void addScaledCell(OperatingConditions *op_cond,
|
||||
LibertyCell *scaled_cell);
|
||||
unsigned addTimingArcSet(TimingArcSet *set);
|
||||
void addInternalPower(InternalPower *power);
|
||||
void addInternalPowerAttrs(InternalPowerAttrs *attrs);
|
||||
void addLeakagePower(LeakagePower *power);
|
||||
TimingArcSet *makeTimingArcSet(LibertyPort *from,
|
||||
LibertyPort *to,
|
||||
LibertyPort *related_out,
|
||||
const TimingRole *role,
|
||||
TimingArcAttrsPtr attrs);
|
||||
void makeInternalPower(LibertyPort *port,
|
||||
LibertyPort *related_port,
|
||||
const std::string &related_pg_pin,
|
||||
const std::shared_ptr<FuncExpr> &when,
|
||||
InternalPowerModels &models);
|
||||
void makeLeakagePower(LibertyPort *related_pg_port,
|
||||
FuncExpr *when,
|
||||
float power);
|
||||
void setLeakagePower(float leakage);
|
||||
void setOcvArcDepth(float depth);
|
||||
void setOcvDerate(OcvDerate *derate);
|
||||
void addOcvDerate(OcvDerate *derate);
|
||||
void setTestCell(TestCell *test);
|
||||
void setHasInferedRegTimingArcs(bool infered);
|
||||
void setSceneCell(LibertyCell *scene_cell,
|
||||
|
|
@ -585,8 +648,6 @@ protected:
|
|||
void translatePresetClrCheckRoles();
|
||||
void inferLatchRoles(Report *report,
|
||||
Debug *debug);
|
||||
void deleteInternalPowerAttrs();
|
||||
void makeTimingArcMap(Report *report);
|
||||
void makeTimingArcPortMaps();
|
||||
bool hasBufferFunc(const LibertyPort *input,
|
||||
const LibertyPort *output) const;
|
||||
|
|
@ -612,12 +673,9 @@ protected:
|
|||
TimingArcSetSeq timing_arc_sets_;
|
||||
TimingArcSetSet timing_arc_set_set_;
|
||||
LibertyPortPairTimingArcMap port_timing_arc_set_map_;
|
||||
LibertyPortTimingArcMap timing_arc_set_from_map_;
|
||||
LibertyPortTimingArcMap timing_arc_set_to_map_;
|
||||
bool has_infered_reg_timing_arcs_;
|
||||
InternalPowerSeq internal_powers_;
|
||||
PortInternalPowerMap port_internal_powers_;
|
||||
InternalPowerAttrsSeq internal_power_attrs_;
|
||||
LeakagePowerSeq leakage_powers_;
|
||||
SequentialSeq sequentials_;
|
||||
PortToSequentialMap port_to_seq_map_;
|
||||
|
|
@ -627,10 +685,10 @@ protected:
|
|||
ScaleFactors *scale_factors_;
|
||||
ScaledCellMap scaled_cells_;
|
||||
TestCell *test_cell_;
|
||||
// Latch D->Q to LatchEnable.
|
||||
LatchEnableMap latch_d_to_q_map_;
|
||||
// Latch EN->D setup to LatchEnable.
|
||||
LatchEnableMap latch_check_map_;
|
||||
// Latch D->Q to LatchEnable index.
|
||||
LatchEnableIndexMap latch_d_to_q_map_;
|
||||
// Latch EN->D setup to LatchEnable index.
|
||||
LatchEnableIndexMap latch_check_map_;
|
||||
LatchEnableSeq latch_enables_;
|
||||
// Ports that have latch D->Q timing arc sets from them.
|
||||
LibertyPortSet latch_data_ports_;
|
||||
|
|
@ -834,10 +892,6 @@ public:
|
|||
float clkTreeDelay(float in_slew,
|
||||
const RiseFall *from_rf,
|
||||
const MinMax *min_max) const;
|
||||
void setClkTreeDelay(const TableModel *model,
|
||||
const RiseFall *from_rf,
|
||||
const RiseFall *to_rf,
|
||||
const MinMax *min_max);
|
||||
// deprecated 2024-06-22
|
||||
RiseFallMinMax clkTreeDelays() const __attribute__ ((deprecated));
|
||||
// deprecated 2024-02-27
|
||||
|
|
@ -898,8 +952,6 @@ protected:
|
|||
std::vector<LibertyPort*> scene_ports_;
|
||||
ReceiverModelPtr receiver_model_;
|
||||
DriverWaveform *driver_waveform_[RiseFall::index_count];
|
||||
// Redundant with clock_tree_path_delay timing arcs but faster to access.
|
||||
const TableModel *clk_tree_delay_[RiseFall::index_count][RiseFall::index_count][MinMax::index_count];
|
||||
|
||||
unsigned int min_pulse_width_exists_:RiseFall::index_count;
|
||||
bool min_period_exists_:1;
|
||||
|
|
@ -1009,10 +1061,10 @@ protected:
|
|||
class BusDcl
|
||||
{
|
||||
public:
|
||||
BusDcl(const char *name,
|
||||
BusDcl(std::string name,
|
||||
int from,
|
||||
int to);
|
||||
const char *name() const { return name_.c_str(); }
|
||||
const std::string &name() const { return name_; }
|
||||
int from() const { return from_; }
|
||||
int to() const { return to_; }
|
||||
|
||||
|
|
@ -1026,18 +1078,16 @@ protected:
|
|||
class ModeDef
|
||||
{
|
||||
public:
|
||||
~ModeDef();
|
||||
const char *name() const { return name_.c_str(); }
|
||||
const std::string &name() const { return name_; }
|
||||
ModeValueDef *defineValue(const char *value,
|
||||
FuncExpr *cond,
|
||||
const char *sdf_cond);
|
||||
ModeValueDef *findValueDef(const char *value);
|
||||
ModeValueMap *values() { return &values_; }
|
||||
const ModeValueDef *findValueDef(const char *value) const;
|
||||
const ModeValueMap *values() const { return &values_; }
|
||||
|
||||
explicit ModeDef(std::string name);
|
||||
|
||||
protected:
|
||||
// Private to LibertyCell::makeModeDef.
|
||||
ModeDef(const char *name);
|
||||
|
||||
std::string name_;
|
||||
ModeValueMap values_;
|
||||
|
||||
|
|
@ -1045,41 +1095,19 @@ private:
|
|||
friend class LibertyCell;
|
||||
};
|
||||
|
||||
// Mode definition mode_value group.
|
||||
class ModeValueDef
|
||||
{
|
||||
public:
|
||||
~ModeValueDef();
|
||||
const char *value() const { return value_.c_str(); }
|
||||
FuncExpr *cond() const { return cond_; }
|
||||
void setCond(FuncExpr *cond);
|
||||
const char *sdfCond() const { return sdf_cond_.c_str(); }
|
||||
void setSdfCond(const char *sdf_cond);
|
||||
|
||||
protected:
|
||||
// Private to ModeDef::defineValue.
|
||||
ModeValueDef(const char *value,
|
||||
FuncExpr *cond,
|
||||
const char *sdf_cond);
|
||||
|
||||
std::string value_;
|
||||
FuncExpr *cond_;
|
||||
std::string sdf_cond_;
|
||||
|
||||
private:
|
||||
friend class ModeDef;
|
||||
};
|
||||
|
||||
class TableTemplate
|
||||
{
|
||||
public:
|
||||
TableTemplate(const char *name);
|
||||
TableTemplate(const char *name,
|
||||
TableTemplate(std::string name);
|
||||
TableTemplate(std::string name,
|
||||
TableTemplateType type);
|
||||
TableTemplate(std::string name,
|
||||
TableAxisPtr axis1,
|
||||
TableAxisPtr axis2,
|
||||
TableAxisPtr axis3);
|
||||
const char *name() const { return name_.c_str(); }
|
||||
void setName(const char *name);
|
||||
const std::string &name() const { return name_; }
|
||||
void setName(std::string name);
|
||||
TableTemplateType type() const { return type_; }
|
||||
const TableAxis *axis1() const { return axis1_.get(); }
|
||||
TableAxisPtr axis1ptr() const { return axis1_; }
|
||||
void setAxis1(TableAxisPtr axis);
|
||||
|
|
@ -1092,6 +1120,7 @@ public:
|
|||
|
||||
protected:
|
||||
std::string name_;
|
||||
TableTemplateType type_;
|
||||
TableAxisPtr axis1_;
|
||||
TableAxisPtr axis2_;
|
||||
TableAxisPtr axis3_;
|
||||
|
|
@ -1101,8 +1130,8 @@ class TestCell : public LibertyCell
|
|||
{
|
||||
public:
|
||||
TestCell(LibertyLibrary *library,
|
||||
const char *name,
|
||||
const char *filename);
|
||||
std::string name,
|
||||
std::string filename);
|
||||
|
||||
protected:
|
||||
};
|
||||
|
|
@ -1110,9 +1139,9 @@ protected:
|
|||
class OcvDerate
|
||||
{
|
||||
public:
|
||||
OcvDerate(const char *name);
|
||||
OcvDerate(std::string name);
|
||||
~OcvDerate();
|
||||
const char *name() const { return name_; }
|
||||
const std::string &name() const { return name_; }
|
||||
const Table *derateTable(const RiseFall *rf,
|
||||
const EarlyLate *early_late,
|
||||
PathType path_type);
|
||||
|
|
@ -1122,7 +1151,7 @@ public:
|
|||
TablePtr derate);
|
||||
|
||||
private:
|
||||
const char *name_;
|
||||
std::string name_;
|
||||
// [rf_type][derate_type][path_type]
|
||||
TablePtr derate_[RiseFall::index_count][EarlyLate::index_count][path_type_count];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class StatetableRow;
|
|||
|
||||
using LibertyLibrarySeq = std::vector<LibertyLibrary*>;
|
||||
using LibertyCellSeq = std::vector<LibertyCell*>;
|
||||
using SequentialSeq = std::vector<Sequential*>;
|
||||
using SequentialSeq = std::vector<Sequential>;
|
||||
using LibertyCellEquivMap = std::map<LibertyCell*, LibertyCellSeq*>;
|
||||
using LibertyPortSeq = std::vector<LibertyPort*>;
|
||||
using LibertyPortSet = std::set<LibertyPort*>;
|
||||
|
|
|
|||
|
|
@ -801,7 +801,7 @@ public:
|
|||
WireloadMode wireloadMode() const { return wireload_mode_; };
|
||||
void setWireloadMode(WireloadMode mode);
|
||||
const WireloadSelection *wireloadSelection(const MinMax *min_max);
|
||||
void setWireloadSelection(WireloadSelection *selection,
|
||||
void setWireloadSelection(const WireloadSelection *selection,
|
||||
const MinMaxAll *min_max);
|
||||
|
||||
// STA interface.
|
||||
|
|
@ -1418,7 +1418,7 @@ protected:
|
|||
float max_area_;
|
||||
Wireload *wireload_[MinMax::index_count];
|
||||
WireloadMode wireload_mode_;
|
||||
WireloadSelection *wireload_selection_[MinMax::index_count];
|
||||
const WireloadSelection *wireload_selection_[MinMax::index_count];
|
||||
|
||||
private:
|
||||
friend class WriteSdc;
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@ public:
|
|||
LibertyPort *output() const { return output_; }
|
||||
LibertyPort *outputInv() const { return output_inv_; }
|
||||
|
||||
protected:
|
||||
// clock/data are:
|
||||
// clocked_on/next_state for registers
|
||||
// enable/data for latches
|
||||
|
|
@ -89,7 +88,12 @@ protected:
|
|||
LogicValue clr_preset_out_inv,
|
||||
LibertyPort *output,
|
||||
LibertyPort *output_inv);
|
||||
Sequential(Sequential &&other) noexcept;
|
||||
Sequential(const Sequential &) = delete;
|
||||
Sequential &operator=(Sequential &&) noexcept;
|
||||
Sequential &operator=(const Sequential &) = delete;
|
||||
|
||||
protected:
|
||||
bool is_register_;
|
||||
FuncExpr *clock_;
|
||||
FuncExpr *data_;
|
||||
|
|
|
|||
|
|
@ -153,6 +153,10 @@ public:
|
|||
Scene *scene,
|
||||
const MinMaxAll *min_max,
|
||||
bool infer_latches);
|
||||
// tmp public
|
||||
void readLibertyAfter(LibertyLibrary *liberty,
|
||||
Scene *scene,
|
||||
const MinMax *min_max);
|
||||
bool readVerilog(const char *filename);
|
||||
// Network readers call this to notify the Sta to delete any previously
|
||||
// linked network.
|
||||
|
|
@ -1577,9 +1581,6 @@ protected:
|
|||
const Mode *mode);
|
||||
void findRegisterPreamble(const Mode *mode);
|
||||
bool crossesHierarchy(Edge *edge) const;
|
||||
void readLibertyAfter(LibertyLibrary *liberty,
|
||||
Scene *scene,
|
||||
const MinMax *min_max);
|
||||
void powerPreamble();
|
||||
void powerPreamble(const Scene *scene);
|
||||
virtual void replaceCell(Instance *inst,
|
||||
|
|
|
|||
|
|
@ -192,6 +192,8 @@ char *
|
|||
makeTmpString(std::string &str);
|
||||
bool
|
||||
isTmpString(const char *str);
|
||||
void
|
||||
deleteTmpStrings();
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "MinMax.hh"
|
||||
|
|
@ -39,13 +40,15 @@ class Unit;
|
|||
class Units;
|
||||
class Report;
|
||||
class Table;
|
||||
class TableModel;
|
||||
class TableAxis;
|
||||
class OutputWaveforms;
|
||||
class Table1;
|
||||
|
||||
using FloatSeq = std::vector<float>;
|
||||
using FloatTable = std::vector<FloatSeq*>;
|
||||
using Table1Seq = std::vector<Table1*>;
|
||||
using Waveform = Table1;
|
||||
using FloatTable = std::vector<FloatSeq>;
|
||||
// Sequence of 1D tables (order 1).
|
||||
using Table1Seq = std::vector<Table*>;
|
||||
using Waveform = Table;
|
||||
|
||||
TableAxisVariable
|
||||
stringTableAxisVariable(const char *variable);
|
||||
|
|
@ -65,7 +68,7 @@ public:
|
|||
TableModel *slew_sigma_models[EarlyLate::index_count],
|
||||
ReceiverModelPtr receiver_model,
|
||||
OutputWaveforms *output_waveforms);
|
||||
virtual ~GateTableModel();
|
||||
~GateTableModel() override;
|
||||
void gateDelay(const Pvt *pvt,
|
||||
float in_slew,
|
||||
float load_cap,
|
||||
|
|
@ -89,10 +92,12 @@ public:
|
|||
int digits) const override;
|
||||
float driveResistance(const Pvt *pvt) const override;
|
||||
|
||||
const TableModel *delayModel() const { return delay_model_; }
|
||||
const TableModel *slewModel() const { return slew_model_; }
|
||||
const TableModel *delayModel() const { return delay_model_.get(); }
|
||||
const TableModel *slewModel() const { return slew_model_.get(); }
|
||||
const TableModel *delaySigmaModel(const EarlyLate *el) const;
|
||||
const TableModel *slewSigmaModel(const EarlyLate *el) const;
|
||||
const ReceiverModel *receiverModel() const { return receiver_model_.get(); }
|
||||
OutputWaveforms *outputWaveforms() const { return output_waveforms_; }
|
||||
OutputWaveforms *outputWaveforms() const { return output_waveforms_.get(); }
|
||||
// Check the axes before making the model.
|
||||
// Return true if the model axes are supported.
|
||||
static bool checkAxes(const TablePtr &table);
|
||||
|
|
@ -129,12 +134,12 @@ protected:
|
|||
float &axis_value3) const;
|
||||
static bool checkAxis(const TableAxis *axis);
|
||||
|
||||
TableModel *delay_model_;
|
||||
TableModel *delay_sigma_models_[EarlyLate::index_count];
|
||||
TableModel *slew_model_;
|
||||
TableModel *slew_sigma_models_[EarlyLate::index_count];
|
||||
std::unique_ptr<TableModel> delay_model_;
|
||||
std::array<std::unique_ptr<TableModel>, EarlyLate::index_count> delay_sigma_models_;
|
||||
std::unique_ptr<TableModel> slew_model_;
|
||||
std::array<std::unique_ptr<TableModel>, EarlyLate::index_count> slew_sigma_models_;
|
||||
ReceiverModelPtr receiver_model_;
|
||||
OutputWaveforms *output_waveforms_;
|
||||
std::unique_ptr<OutputWaveforms> output_waveforms_;
|
||||
};
|
||||
|
||||
class CheckTableModel : public CheckTimingModel
|
||||
|
|
@ -143,7 +148,7 @@ public:
|
|||
CheckTableModel(LibertyCell *cell,
|
||||
TableModel *model,
|
||||
TableModel *sigma_models[EarlyLate::index_count]);
|
||||
virtual ~CheckTableModel();
|
||||
~CheckTableModel() override;
|
||||
ArcDelay checkDelay(const Pvt *pvt,
|
||||
float from_slew,
|
||||
float to_slew,
|
||||
|
|
@ -156,7 +161,8 @@ public:
|
|||
float related_out_cap,
|
||||
bool pocv_enabled,
|
||||
int digits) const override;
|
||||
const TableModel *model() const { return model_; }
|
||||
const TableModel *model() const { return model_.get(); }
|
||||
const TableModel *sigmaModel(const EarlyLate *el) const;
|
||||
|
||||
// Check the axes before making the model.
|
||||
// Return true if the model axes are supported.
|
||||
|
|
@ -190,14 +196,156 @@ protected:
|
|||
int digits) const;
|
||||
static bool checkAxis(const TableAxis *axis);
|
||||
|
||||
TableModel *model_;
|
||||
TableModel *sigma_models_[EarlyLate::index_count];
|
||||
std::unique_ptr<TableModel> model_;
|
||||
std::array<std::unique_ptr<TableModel>, EarlyLate::index_count> sigma_models_;
|
||||
};
|
||||
|
||||
class TableAxis
|
||||
{
|
||||
public:
|
||||
TableAxis(TableAxisVariable variable,
|
||||
FloatSeq &&values);
|
||||
TableAxisVariable variable() const { return variable_; }
|
||||
const char *variableString() const;
|
||||
const Unit *unit(const Units *units);
|
||||
size_t size() const { return values_.size(); }
|
||||
bool inBounds(float value) const;
|
||||
float axisValue(size_t index) const { return values_[index]; }
|
||||
// Find the index for value such that axis[index] <= value < axis[index+1].
|
||||
size_t findAxisIndex(float value) const;
|
||||
void findAxisIndex(float value,
|
||||
// Return values.
|
||||
size_t &index,
|
||||
bool &exists) const;
|
||||
size_t findAxisClosestIndex(float value) const;
|
||||
const FloatSeq &values() const { return values_; }
|
||||
float min() const;
|
||||
float max() const;
|
||||
|
||||
private:
|
||||
TableAxisVariable variable_;
|
||||
FloatSeq values_;
|
||||
};
|
||||
|
||||
// 0, 1, 2, or 3 dimension float tables.
|
||||
class Table
|
||||
{
|
||||
public:
|
||||
Table();
|
||||
explicit Table(float value);
|
||||
Table(FloatSeq *values,
|
||||
TableAxisPtr axis1);
|
||||
Table(FloatSeq &&values,
|
||||
TableAxisPtr axis1);
|
||||
Table(FloatTable &&values,
|
||||
TableAxisPtr axis1,
|
||||
TableAxisPtr axis2);
|
||||
Table(FloatTable &&values,
|
||||
TableAxisPtr axis1,
|
||||
TableAxisPtr axis2,
|
||||
TableAxisPtr axis3);
|
||||
Table(Table &&table);
|
||||
Table(const Table &table);
|
||||
Table &operator=(Table &&table);
|
||||
|
||||
void setScaleFactorType(ScaleFactorType type);
|
||||
int order() const { return order_; }
|
||||
const TableAxis *axis1() const { return axis1_.get(); }
|
||||
const TableAxis *axis2() const { return axis2_.get(); }
|
||||
const TableAxis *axis3() const { return axis3_.get(); }
|
||||
const TableAxisPtr axis1ptr() const { return axis1_; }
|
||||
void setIsScaled(bool is_scaled);
|
||||
|
||||
float value(size_t axis_idx1,
|
||||
size_t axis_idx2,
|
||||
size_t axis_idx3) const;
|
||||
// Single-index value (order 1 only).
|
||||
float value(size_t index1) const;
|
||||
// Two-index value (order 2 and 3).
|
||||
float value(size_t axis_index1,
|
||||
size_t axis_index2) const;
|
||||
|
||||
// Table interpolated lookup.
|
||||
float findValue(float axis_value1,
|
||||
float axis_value2,
|
||||
float axis_value3) const;
|
||||
// One-argument lookup (order 1).
|
||||
void findValue(float axis_value1,
|
||||
float &value,
|
||||
bool &extrapolated) const;
|
||||
float findValue(float axis_value1) const;
|
||||
float findValueClip(float axis_value1) const;
|
||||
// Table interpolated lookup with scale factor.
|
||||
float findValue(const LibertyLibrary *library,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float axis_value1,
|
||||
float axis_value2,
|
||||
float axis_value3) const;
|
||||
|
||||
std::string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const;
|
||||
void report(const Units *units,
|
||||
Report *report) const;
|
||||
|
||||
// Order 1: pointer to value sequence (nullptr if not order 1).
|
||||
FloatSeq *values() const;
|
||||
// Order 2 and 3: pointer to value table (nullptr otherwise).
|
||||
FloatTable *values3();
|
||||
const FloatTable *values3() const;
|
||||
|
||||
private:
|
||||
void clear();
|
||||
std::string reportValueOrder0(const char *result_name,
|
||||
const char *comment1,
|
||||
const Unit *table_unit,
|
||||
int digits) const;
|
||||
std::string reportValueOrder1(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const;
|
||||
std::string reportValueOrder2(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const;
|
||||
std::string reportValueOrder3(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const;
|
||||
|
||||
int order_;
|
||||
float value_; // order 0 only
|
||||
FloatSeq values1_; // order 1 only
|
||||
FloatTable values_table_; // order 2 and 3
|
||||
TableAxisPtr axis1_;
|
||||
TableAxisPtr axis2_;
|
||||
TableAxisPtr axis3_;
|
||||
};
|
||||
|
||||
// Wrapper class for Table to apply scale factors.
|
||||
class TableModel
|
||||
{
|
||||
public:
|
||||
TableModel();
|
||||
TableModel(TablePtr table,
|
||||
TableTemplate *tbl_template,
|
||||
ScaleFactorType scale_factor_type,
|
||||
|
|
@ -205,6 +353,9 @@ public:
|
|||
void setScaleFactorType(ScaleFactorType type);
|
||||
int order() const;
|
||||
TableTemplate *tblTemplate() const { return tbl_template_; }
|
||||
const TablePtr &table() const { return table_; }
|
||||
ScaleFactorType scaleFactorType() const;
|
||||
int rfIndex() const { return rf_index_; }
|
||||
const TableAxis *axis1() const;
|
||||
const TableAxis *axis2() const;
|
||||
const TableAxis *axis3() const;
|
||||
|
|
@ -249,243 +400,19 @@ protected:
|
|||
bool is_scaled_:1;
|
||||
};
|
||||
|
||||
// Abstract base class for 0, 1, 2, or 3 dimesnion float tables.
|
||||
class Table
|
||||
{
|
||||
public:
|
||||
Table() {}
|
||||
virtual ~Table() {}
|
||||
void setScaleFactorType(ScaleFactorType type);
|
||||
virtual int order() const = 0;
|
||||
virtual const TableAxis *axis1() const { return nullptr; }
|
||||
virtual const TableAxis *axis2() const { return nullptr; }
|
||||
virtual const TableAxis *axis3() const { return nullptr; }
|
||||
void setIsScaled(bool is_scaled);
|
||||
virtual float value(size_t axis_idx1,
|
||||
size_t axis_idx2,
|
||||
size_t axis_idx3) const = 0;
|
||||
// Table interpolated lookup.
|
||||
virtual float findValue(float axis_value1,
|
||||
float axis_value2,
|
||||
float axis_value3) const = 0;
|
||||
// Table interpolated lookup with scale factor.
|
||||
float findValue(const LibertyLibrary *library,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float axis_value1,
|
||||
float axis_value2,
|
||||
float axis_value3) const;
|
||||
virtual std::string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const = 0;
|
||||
virtual void report(const Units *units,
|
||||
Report *report) const = 0;
|
||||
};
|
||||
|
||||
// Zero dimension (scalar) table.
|
||||
class Table0 : public Table
|
||||
{
|
||||
public:
|
||||
Table0(float value);
|
||||
int order() const override { return 0; }
|
||||
float value(size_t axis_index1,
|
||||
size_t axis_index2,
|
||||
size_t axis_index3) const override;
|
||||
float findValue(float axis_value1,
|
||||
float axis_value2,
|
||||
float axis_value3) const override;
|
||||
std::string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const override;
|
||||
void report(const Units *units,
|
||||
Report *report) const override;
|
||||
using Table::findValue;
|
||||
|
||||
private:
|
||||
float value_;
|
||||
};
|
||||
|
||||
// One dimensional table.
|
||||
class Table1 : public Table
|
||||
{
|
||||
public:
|
||||
Table1();
|
||||
Table1(FloatSeq *values,
|
||||
TableAxisPtr axis1);
|
||||
virtual ~Table1();
|
||||
Table1(Table1 &&table);
|
||||
Table1(const Table1 &table);
|
||||
Table1 &operator= (Table1 &&table);
|
||||
int order() const override { return 1; }
|
||||
const TableAxis *axis1() const override { return axis1_.get(); }
|
||||
const TableAxisPtr axis1ptr() const { return axis1_; }
|
||||
float value(size_t axis_index1,
|
||||
size_t axis_index2,
|
||||
size_t axis_index3) const override;
|
||||
float findValue(float value1,
|
||||
float value2,
|
||||
float value3) const override;
|
||||
std::string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const override;
|
||||
void report(const Units *units,
|
||||
Report *report) const override;
|
||||
|
||||
// Table1 specific functions.
|
||||
float value(size_t index1) const;
|
||||
void findValue(float axis_value1,
|
||||
// Return values.
|
||||
float &value,
|
||||
bool &extrapolated) const;
|
||||
float findValue(float axis_value1) const;
|
||||
float findValueClip(float axis_value1) const;
|
||||
FloatSeq *values() const { return values_; }
|
||||
using Table::findValue;
|
||||
|
||||
private:
|
||||
FloatSeq *values_;
|
||||
TableAxisPtr axis1_;
|
||||
};
|
||||
|
||||
// Two dimensional table.
|
||||
class Table2 : public Table
|
||||
{
|
||||
public:
|
||||
Table2(FloatTable *values,
|
||||
TableAxisPtr axis1,
|
||||
TableAxisPtr axis2);
|
||||
virtual ~Table2();
|
||||
int order() const override { return 2; }
|
||||
const TableAxis *axis1() const override { return axis1_.get(); }
|
||||
const TableAxis *axis2() const override { return axis2_.get(); }
|
||||
float value(size_t axis_index1,
|
||||
size_t axis_index2,
|
||||
size_t axis_index3) const override;
|
||||
float findValue(float value1,
|
||||
float value2,
|
||||
float value3) const override;
|
||||
std::string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const override;
|
||||
void report(const Units *units,
|
||||
Report *report) const override;
|
||||
|
||||
// Table2 specific functions.
|
||||
float value(size_t axis_index1,
|
||||
size_t axis_index2) const;
|
||||
FloatTable *values3() { return values_; }
|
||||
|
||||
using Table::findValue;
|
||||
|
||||
protected:
|
||||
FloatTable *values_;
|
||||
// Row.
|
||||
TableAxisPtr axis1_;
|
||||
// Column.
|
||||
TableAxisPtr axis2_;
|
||||
};
|
||||
|
||||
// Three dimensional table.
|
||||
class Table3 : public Table2
|
||||
{
|
||||
public:
|
||||
Table3(FloatTable *values,
|
||||
TableAxisPtr axis1,
|
||||
TableAxisPtr axis2,
|
||||
TableAxisPtr axis3);
|
||||
virtual ~Table3() {}
|
||||
int order() const override { return 3; }
|
||||
const TableAxis *axis1() const override { return axis1_.get(); }
|
||||
const TableAxis *axis2() const override { return axis2_.get(); }
|
||||
const TableAxis *axis3() const override { return axis3_.get(); }
|
||||
float value(size_t axis_index1,
|
||||
size_t axis_index2,
|
||||
size_t axis_index3) const override;
|
||||
float findValue(float value1,
|
||||
float value2,
|
||||
float value3) const override;
|
||||
std::string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const override;
|
||||
void report(const Units *units,
|
||||
Report *report) const override;
|
||||
using Table::findValue;
|
||||
|
||||
private:
|
||||
TableAxisPtr axis3_;
|
||||
};
|
||||
|
||||
class TableAxis
|
||||
{
|
||||
public:
|
||||
TableAxis(TableAxisVariable variable,
|
||||
FloatSeq *values);
|
||||
~TableAxis();
|
||||
TableAxisVariable variable() const { return variable_; }
|
||||
const char *variableString() const;
|
||||
const Unit *unit(const Units *units);
|
||||
size_t size() const { return values_->size(); }
|
||||
bool inBounds(float value) const;
|
||||
float axisValue(size_t index) const { return (*values_)[index]; }
|
||||
// Find the index for value such that axis[index] <= value < axis[index+1].
|
||||
size_t findAxisIndex(float value) const;
|
||||
void findAxisIndex(float value,
|
||||
// Return values.
|
||||
size_t &index,
|
||||
bool &exists) const;
|
||||
size_t findAxisClosestIndex(float value) const;
|
||||
FloatSeq *values() const { return values_; }
|
||||
float min() const;
|
||||
float max() const;
|
||||
|
||||
private:
|
||||
TableAxisVariable variable_;
|
||||
FloatSeq *values_;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
class ReceiverModel
|
||||
{
|
||||
public:
|
||||
~ReceiverModel();
|
||||
void setCapacitanceModel(TableModel *table_model,
|
||||
void setCapacitanceModel(TableModel table_model,
|
||||
size_t segment,
|
||||
const RiseFall *rf);
|
||||
static bool checkAxes(TablePtr table);
|
||||
|
||||
private:
|
||||
std::vector<TableModel*> capacitance_models_;
|
||||
std::vector<TableModel> capacitance_models_;
|
||||
};
|
||||
|
||||
// Two dimensional (slew/cap) table of one dimensional time/current tables.
|
||||
|
|
@ -496,7 +423,7 @@ public:
|
|||
TableAxisPtr cap_axis,
|
||||
const RiseFall *rf,
|
||||
Table1Seq ¤t_waveforms,
|
||||
Table1 *ref_times);
|
||||
Table ref_times);
|
||||
~OutputWaveforms();
|
||||
const RiseFall *rf() const { return rf_; }
|
||||
const TableAxis *slewAxis() const { return slew_axis_.get(); }
|
||||
|
|
@ -523,18 +450,18 @@ public:
|
|||
float cap);
|
||||
static bool checkAxes(const TableTemplate *tbl_template);
|
||||
|
||||
Table1 currentWaveform(float slew,
|
||||
float cap);
|
||||
Table currentWaveform(float slew,
|
||||
float cap);
|
||||
// Waveform closest to slew/cap; no interpolation.
|
||||
const Table1 *currentWaveformRaw(float slew,
|
||||
float cap);
|
||||
Table1 voltageWaveform(float in_slew,
|
||||
float load_cap);
|
||||
const Table *currentWaveformRaw(float slew,
|
||||
float cap);
|
||||
Table voltageWaveform(float in_slew,
|
||||
float load_cap);
|
||||
// Waveform closest to slew/cap; no interpolation.
|
||||
const Table1 *voltageWaveformRaw(float slew,
|
||||
float cap);
|
||||
Table1 voltageCurrentWaveform(float slew,
|
||||
float cap);
|
||||
const Table *voltageWaveformRaw(float slew,
|
||||
float cap);
|
||||
Table voltageCurrentWaveform(float slew,
|
||||
float cap);
|
||||
// V/I for last segment of min slew/max cap.
|
||||
float finalResistance();
|
||||
|
||||
|
|
@ -563,10 +490,10 @@ private:
|
|||
// Column.
|
||||
TableAxisPtr cap_axis_;
|
||||
const RiseFall *rf_;
|
||||
Table1Seq current_waveforms_; // from liberty
|
||||
Table1Seq current_waveforms_; // from liberty (1D tables)
|
||||
Table1Seq voltage_waveforms_;
|
||||
Table1Seq voltage_currents_;
|
||||
Table1 *ref_times_;
|
||||
Table ref_times_;
|
||||
float vdd_;
|
||||
static constexpr size_t voltage_waveform_step_count_ = 100;
|
||||
};
|
||||
|
|
@ -577,7 +504,7 @@ public:
|
|||
DriverWaveform(const std::string &name,
|
||||
TablePtr waveforms);
|
||||
const char *name() const { return name_.c_str(); }
|
||||
Table1 waveform(float slew);
|
||||
Table waveform(float slew);
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
|
@ -39,7 +40,6 @@ class WireTimingArc;
|
|||
class GateTableModel;
|
||||
class Scene;
|
||||
|
||||
using TimingArcIndex = int;
|
||||
using TimingArcSeq = std::vector<TimingArc*>;
|
||||
using ScaledTimingModelMap = std::map<const OperatingConditions*, TimingModel*>;
|
||||
|
||||
|
|
@ -106,16 +106,16 @@ public:
|
|||
void setTimingSense(TimingSense sense);
|
||||
FuncExpr *cond() const { return cond_; }
|
||||
void setCond(FuncExpr *cond);
|
||||
const char *sdfCond() const { return sdf_cond_; }
|
||||
void setSdfCond(const char *cond);
|
||||
const char *sdfCondStart() const { return sdf_cond_start_; }
|
||||
void setSdfCondStart(const char *cond);
|
||||
const char *sdfCondEnd() const { return sdf_cond_end_; }
|
||||
void setSdfCondEnd(const char *cond);
|
||||
const char *modeName() const { return mode_name_; }
|
||||
void setModeName(const char *name);
|
||||
const char *modeValue() const { return mode_value_; }
|
||||
void setModeValue(const char *value);
|
||||
const std::string &sdfCond() const { return sdf_cond_; }
|
||||
void setSdfCond(const std::string &cond);
|
||||
const std::string &sdfCondStart() const { return sdf_cond_start_; }
|
||||
void setSdfCondStart(const std::string &cond);
|
||||
const std::string &sdfCondEnd() const { return sdf_cond_end_; }
|
||||
void setSdfCondEnd(const std::string &cond);
|
||||
const std::string &modeName() const { return mode_name_; }
|
||||
void setModeName(const std::string &name);
|
||||
const std::string &modeValue() const { return mode_value_; }
|
||||
void setModeValue(const std::string &value);
|
||||
TimingModel *model(const RiseFall *rf) const;
|
||||
void setModel(const RiseFall *rf,
|
||||
TimingModel *model);
|
||||
|
|
@ -126,11 +126,11 @@ protected:
|
|||
TimingType timing_type_;
|
||||
TimingSense timing_sense_;
|
||||
FuncExpr *cond_;
|
||||
const char *sdf_cond_;
|
||||
const char *sdf_cond_start_;
|
||||
const char *sdf_cond_end_;
|
||||
const char *mode_name_;
|
||||
const char *mode_value_;
|
||||
std::string sdf_cond_;
|
||||
std::string sdf_cond_start_;
|
||||
std::string sdf_cond_end_;
|
||||
std::string mode_name_;
|
||||
std::string mode_value_;
|
||||
float ocv_arc_depth_;
|
||||
TimingModel *models_[RiseFall::index_count];
|
||||
};
|
||||
|
|
@ -142,13 +142,9 @@ protected:
|
|||
// See ~LibertyCell for delete of TimingArcSet members.
|
||||
class TimingArcSet
|
||||
{
|
||||
friend class LibertyCell;
|
||||
|
||||
public:
|
||||
TimingArcSet(LibertyCell *cell,
|
||||
LibertyPort *from,
|
||||
LibertyPort *to,
|
||||
LibertyPort *related_out,
|
||||
const TimingRole *role,
|
||||
TimingArcAttrsPtr attrs);
|
||||
virtual ~TimingArcSet();
|
||||
LibertyCell *libertyCell() const;
|
||||
LibertyPort *from() const { return from_; }
|
||||
|
|
@ -156,7 +152,9 @@ public:
|
|||
bool isWire() const;
|
||||
LibertyPort *relatedOut() const { return related_out_; }
|
||||
const TimingRole *role() const { return role_; };
|
||||
TimingType timingType() const { return attrs_->timingType(); }
|
||||
TimingSense sense() const;
|
||||
TimingModel *model(const RiseFall *rf) const { return attrs_->model(rf); }
|
||||
// Rise/fall if the arc set is rising_edge or falling_edge.
|
||||
const RiseFall *isRisingFallingEdge() const;
|
||||
size_t arcCount() const { return arcs_.size(); }
|
||||
|
|
@ -168,7 +166,7 @@ public:
|
|||
TimingArc *&arc2) const;
|
||||
TimingArc *arcTo(const RiseFall *to_rf) const;
|
||||
const TimingArcSeq &arcs() const { return arcs_; }
|
||||
TimingArcIndex addTimingArc(TimingArc *arc);
|
||||
size_t addTimingArc(TimingArc *arc);
|
||||
void deleteTimingArc(TimingArc *arc);
|
||||
TimingArc *findTimingArc(unsigned arc_index);
|
||||
void setRole(const TimingRole *role);
|
||||
|
|
@ -179,14 +177,15 @@ public:
|
|||
void setIsCondDefault(bool is_default);
|
||||
// SDF IOPATHs match sdfCond.
|
||||
// sdfCond (IOPATH) reuses sdfCondStart (timing check) variable.
|
||||
const char *sdfCond() const { return attrs_->sdfCondStart(); }
|
||||
const std::string &sdfCond() const { return attrs_->sdfCondStart(); }
|
||||
// SDF timing checks match sdfCondStart/sdfCondEnd.
|
||||
const char *sdfCondStart() const { return attrs_->sdfCondStart(); }
|
||||
const char *sdfCondEnd() const { return attrs_->sdfCondEnd(); }
|
||||
const char *modeName() const { return attrs_->modeName(); }
|
||||
const char *modeValue() const { return attrs_->modeValue(); }
|
||||
const std::string &sdfCondStart() const { return attrs_->sdfCondStart(); }
|
||||
const std::string &sdfCondEnd() const { return attrs_->sdfCondEnd(); }
|
||||
const std::string &modeName() const { return attrs_->modeName(); }
|
||||
const std::string &modeValue() const { return attrs_->modeValue(); }
|
||||
// Timing arc set index in cell.
|
||||
TimingArcIndex index() const { return index_; }
|
||||
size_t index() const { return index_; }
|
||||
void setIndex(size_t index);
|
||||
// OCV arc depth from timing/cell/library.
|
||||
float ocvArcDepth() const;
|
||||
|
||||
|
|
@ -206,6 +205,13 @@ public:
|
|||
protected:
|
||||
TimingArcSet(const TimingRole *role,
|
||||
TimingArcAttrsPtr attrs);
|
||||
TimingArcSet(LibertyCell *cell,
|
||||
LibertyPort *from,
|
||||
LibertyPort *to,
|
||||
LibertyPort *related_out,
|
||||
const TimingRole *role,
|
||||
TimingArcAttrsPtr attrs,
|
||||
size_t index);
|
||||
|
||||
LibertyPort *from_;
|
||||
LibertyPort *to_;
|
||||
|
|
@ -215,7 +221,7 @@ protected:
|
|||
TimingArcAttrsPtr attrs_;
|
||||
TimingArcSeq arcs_;
|
||||
bool is_cond_default_;
|
||||
unsigned index_;
|
||||
size_t index_;
|
||||
TimingArc *from_arc1_[RiseFall::index_count];
|
||||
TimingArc *from_arc2_[RiseFall::index_count];
|
||||
TimingArc *to_arc_[RiseFall::index_count];
|
||||
|
|
|
|||
|
|
@ -218,8 +218,8 @@ static unsigned
|
|||
hashCellSequentials(const LibertyCell *cell)
|
||||
{
|
||||
unsigned hash = 0;
|
||||
for (const Sequential *seq : cell->sequentials())
|
||||
hash += hashSequential(seq);
|
||||
for (const Sequential &seq : cell->sequentials())
|
||||
hash += hashSequential(&seq);
|
||||
const Statetable *statetable = cell->statetable();
|
||||
if (statetable)
|
||||
hash += hashStatetable(statetable);
|
||||
|
|
@ -380,14 +380,14 @@ equivCellSequentials(const LibertyCell *cell1,
|
|||
for (;
|
||||
seq_itr1 != seqs1.end() && seq_itr2 != seqs2.end();
|
||||
seq_itr1++, seq_itr2++) {
|
||||
const Sequential *seq1 = *seq_itr1;
|
||||
const Sequential *seq2 = *seq_itr2;
|
||||
if (!(FuncExpr::equiv(seq1->clock(), seq2->clock())
|
||||
&& FuncExpr::equiv(seq1->data(), seq2->data())
|
||||
&& LibertyPort::equiv(seq1->output(), seq2->output())
|
||||
&& LibertyPort::equiv(seq1->outputInv(), seq2->outputInv())
|
||||
&& FuncExpr::equiv(seq1->clear(), seq2->clear())
|
||||
&& FuncExpr::equiv(seq1->preset(), seq2->preset())))
|
||||
const Sequential &seq1 = *seq_itr1;
|
||||
const Sequential &seq2 = *seq_itr2;
|
||||
if (!(FuncExpr::equiv(seq1.clock(), seq2.clock())
|
||||
&& FuncExpr::equiv(seq1.data(), seq2.data())
|
||||
&& LibertyPort::equiv(seq1.output(), seq2.output())
|
||||
&& LibertyPort::equiv(seq1.outputInv(), seq2.outputInv())
|
||||
&& FuncExpr::equiv(seq1.clear(), seq2.clear())
|
||||
&& FuncExpr::equiv(seq1.preset(), seq2.preset())))
|
||||
return false;
|
||||
}
|
||||
return seq_itr1 == seqs1.end() && seq_itr2 == seqs2.end();
|
||||
|
|
|
|||
|
|
@ -89,13 +89,17 @@ FuncExpr::FuncExpr(Op op,
|
|||
{
|
||||
}
|
||||
|
||||
void
|
||||
FuncExpr::deleteSubexprs()
|
||||
FuncExpr::~FuncExpr()
|
||||
{
|
||||
if (left_)
|
||||
left_->deleteSubexprs();
|
||||
if (right_)
|
||||
right_->deleteSubexprs();
|
||||
delete left_;
|
||||
delete right_;
|
||||
}
|
||||
|
||||
void
|
||||
FuncExpr::shallowDelete()
|
||||
{
|
||||
left_ = nullptr;
|
||||
right_ = nullptr;
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
|
@ -209,7 +213,7 @@ FuncExpr::to_string(bool with_parens) const
|
|||
return port_->name();
|
||||
case Op::not_: {
|
||||
string result = "!";
|
||||
result += left_->to_string(true);
|
||||
result += left_ ? left_->to_string(true) : "?";
|
||||
return result;
|
||||
}
|
||||
case Op::or_:
|
||||
|
|
@ -235,9 +239,9 @@ FuncExpr::to_string(bool with_parens,
|
|||
string result;
|
||||
if (with_parens)
|
||||
result += '(';
|
||||
result += left_->to_string(true);
|
||||
result += left_ ? left_->to_string(true) : "?";
|
||||
result += op;
|
||||
result += right_->to_string(true);
|
||||
result += right_ ? right_->to_string(true) : "?";
|
||||
if (with_parens)
|
||||
result += ')';
|
||||
return result;
|
||||
|
|
@ -277,8 +281,9 @@ FuncExpr::bitSubExpr(int bit_offset)
|
|||
return makeXor(left_->bitSubExpr(bit_offset),
|
||||
right_->bitSubExpr(bit_offset));
|
||||
case Op::one:
|
||||
return makeOne();
|
||||
case Op::zero:
|
||||
return this;
|
||||
return makeZero();
|
||||
}
|
||||
// Prevent warnings from lame compilers.
|
||||
return nullptr;
|
||||
|
|
@ -335,15 +340,15 @@ FuncExpr::checkSize(size_t size)
|
|||
}
|
||||
|
||||
FuncExpr *
|
||||
funcExprNot(FuncExpr *expr)
|
||||
FuncExpr::invert()
|
||||
{
|
||||
if (expr->op() == FuncExpr::Op::not_) {
|
||||
FuncExpr *not_expr = expr->left();
|
||||
delete expr;
|
||||
return not_expr;
|
||||
if (op_ == FuncExpr::Op::not_) {
|
||||
FuncExpr *inv = left_;
|
||||
shallowDelete() ;
|
||||
return inv;
|
||||
}
|
||||
else
|
||||
return FuncExpr::makeNot(expr);
|
||||
return FuncExpr::makeNot(this);
|
||||
}
|
||||
|
||||
LibertyPortSet
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
#include "InternalPower.hh"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "FuncExpr.hh"
|
||||
#include "TableModel.hh"
|
||||
#include "Liberty.hh"
|
||||
|
|
@ -31,79 +33,17 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
|
||||
InternalPowerAttrs::InternalPowerAttrs() :
|
||||
when_(nullptr),
|
||||
models_{nullptr, nullptr},
|
||||
related_pg_pin_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
InternalPowerAttrs::~InternalPowerAttrs()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
InternalPowerAttrs::deleteContents()
|
||||
{
|
||||
InternalPowerModel *rise_model = models_[RiseFall::riseIndex()];
|
||||
InternalPowerModel *fall_model = models_[RiseFall::fallIndex()];
|
||||
delete rise_model;
|
||||
if (fall_model != rise_model)
|
||||
delete fall_model;
|
||||
if (when_)
|
||||
when_->deleteSubexprs();
|
||||
stringDelete(related_pg_pin_);
|
||||
}
|
||||
|
||||
InternalPowerModel *
|
||||
InternalPowerAttrs::model(const RiseFall *rf) const
|
||||
{
|
||||
return models_[rf->index()];
|
||||
}
|
||||
|
||||
void
|
||||
InternalPowerAttrs::setWhen(FuncExpr *when)
|
||||
{
|
||||
when_ = when;
|
||||
}
|
||||
|
||||
void
|
||||
InternalPowerAttrs::setModel(const RiseFall *rf,
|
||||
InternalPowerModel *model)
|
||||
{
|
||||
models_[rf->index()] = model;
|
||||
}
|
||||
|
||||
void
|
||||
InternalPowerAttrs::setRelatedPgPin(const char *related_pg_pin)
|
||||
{
|
||||
stringDelete(related_pg_pin_);
|
||||
related_pg_pin_ = stringCopy(related_pg_pin);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
InternalPower::InternalPower(LibertyCell *cell,
|
||||
LibertyPort *port,
|
||||
InternalPower::InternalPower(LibertyPort *port,
|
||||
LibertyPort *related_port,
|
||||
InternalPowerAttrs *attrs) :
|
||||
const std::string &related_pg_pin,
|
||||
const std::shared_ptr<FuncExpr> &when,
|
||||
InternalPowerModels &models) :
|
||||
port_(port),
|
||||
related_port_(related_port),
|
||||
when_(attrs->when()),
|
||||
related_pg_pin_(attrs->relatedPgPin())
|
||||
related_pg_pin_(related_pg_pin),
|
||||
when_(when),
|
||||
models_(models)
|
||||
{
|
||||
for (auto rf : RiseFall::range()) {
|
||||
int rf_index = rf->index();
|
||||
models_[rf_index] = attrs->model(rf);
|
||||
}
|
||||
cell->addInternalPower(this);
|
||||
}
|
||||
|
||||
InternalPower::~InternalPower()
|
||||
{
|
||||
// models_, when_ and related_pg_pin_ are owned by InternalPowerAttrs.
|
||||
}
|
||||
|
||||
LibertyCell *
|
||||
|
|
@ -116,15 +56,22 @@ float
|
|||
InternalPower::power(const RiseFall *rf,
|
||||
const Pvt *pvt,
|
||||
float in_slew,
|
||||
float load_cap)
|
||||
float load_cap) const
|
||||
{
|
||||
InternalPowerModel *model = models_[rf->index()];
|
||||
const std::shared_ptr<InternalPowerModel> &model = models_[rf->index()];
|
||||
if (model)
|
||||
return model->power(libertyCell(), pvt, in_slew, load_cap);
|
||||
else
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
const InternalPowerModel *
|
||||
InternalPower::model(const RiseFall *rf) const
|
||||
{
|
||||
const std::shared_ptr<InternalPowerModel> &m = models_[rf->index()];
|
||||
return m.get();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
InternalPowerModel::InternalPowerModel(TableModel *model) :
|
||||
|
|
@ -153,7 +100,7 @@ InternalPowerModel::power(const LibertyCell *cell,
|
|||
return 0.0;
|
||||
}
|
||||
|
||||
string
|
||||
std::string
|
||||
InternalPowerModel::reportPower(const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float in_slew,
|
||||
|
|
|
|||
|
|
@ -41,6 +41,36 @@ LeakagePower::LeakagePower(LibertyCell *cell,
|
|||
{
|
||||
}
|
||||
|
||||
LeakagePower::LeakagePower(LeakagePower &&other) noexcept
|
||||
{
|
||||
cell_ = other.cell_;
|
||||
related_pg_port_ = other.related_pg_port_;
|
||||
when_ = other.when_;
|
||||
other.when_ = nullptr;
|
||||
power_ = other.power_;
|
||||
}
|
||||
|
||||
LeakagePower::~LeakagePower()
|
||||
{
|
||||
delete when_;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
>>>>>>>
|
||||
|
||||
namespace sta {
|
||||
|
||||
LeakagePower::LeakagePower(LibertyCell *cell,
|
||||
LibertyPort *related_pg_port,
|
||||
FuncExpr *when,
|
||||
float power) :
|
||||
cell_(cell),
|
||||
related_pg_port_(related_pg_port),
|
||||
when_(when),
|
||||
power_(power)
|
||||
{
|
||||
}
|
||||
|
||||
LeakagePower::~LeakagePower()
|
||||
{
|
||||
if (when_)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -237,13 +237,13 @@ find_liberty_cells_matching(const char *pattern,
|
|||
return self->findLibertyCellsMatching(&matcher);
|
||||
}
|
||||
|
||||
Wireload *
|
||||
const Wireload *
|
||||
find_wireload(const char *model_name)
|
||||
{
|
||||
return self->findWireload(model_name);
|
||||
}
|
||||
|
||||
WireloadSelection *
|
||||
const WireloadSelection *
|
||||
find_wireload_selection(const char *selection_name)
|
||||
{
|
||||
return self->findWireloadSelection(selection_name);
|
||||
|
|
@ -364,7 +364,7 @@ scan_signal_type()
|
|||
LibertyPort *from() { return self->from(); }
|
||||
LibertyPort *to() { return self->to(); }
|
||||
const TimingRole *role() { return self->role(); }
|
||||
const char *sdf_cond() { return self->sdfCond(); }
|
||||
const char *sdf_cond() { return self->sdfCond().c_str(); }
|
||||
|
||||
const char *
|
||||
full_name()
|
||||
|
|
@ -448,7 +448,7 @@ voltage_time(float in_slew,
|
|||
return 0.0;
|
||||
}
|
||||
|
||||
Table1
|
||||
Table
|
||||
voltage_waveform(float in_slew,
|
||||
float load_cap)
|
||||
{
|
||||
|
|
@ -456,14 +456,14 @@ voltage_waveform(float in_slew,
|
|||
if (gate_model) {
|
||||
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
||||
if (waveforms) {
|
||||
Table1 waveform = waveforms->voltageWaveform(in_slew, load_cap);
|
||||
Table waveform = waveforms->voltageWaveform(in_slew, load_cap);
|
||||
return waveform;
|
||||
}
|
||||
}
|
||||
return Table1();
|
||||
return Table();
|
||||
}
|
||||
|
||||
const Table1 *
|
||||
const Table *
|
||||
voltage_waveform_raw(float in_slew,
|
||||
float load_cap)
|
||||
{
|
||||
|
|
@ -471,14 +471,14 @@ voltage_waveform_raw(float in_slew,
|
|||
if (gate_model) {
|
||||
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
||||
if (waveforms) {
|
||||
const Table1 *waveform = waveforms->voltageWaveformRaw(in_slew, load_cap);
|
||||
const Table *waveform = waveforms->voltageWaveformRaw(in_slew, load_cap);
|
||||
return waveform;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Table1
|
||||
Table
|
||||
current_waveform(float in_slew,
|
||||
float load_cap)
|
||||
{
|
||||
|
|
@ -486,14 +486,14 @@ current_waveform(float in_slew,
|
|||
if (gate_model) {
|
||||
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
||||
if (waveforms) {
|
||||
Table1 waveform = waveforms->currentWaveform(in_slew, load_cap);
|
||||
Table waveform = waveforms->currentWaveform(in_slew, load_cap);
|
||||
return waveform;
|
||||
}
|
||||
}
|
||||
return Table1();
|
||||
return Table();
|
||||
}
|
||||
|
||||
const Table1 *
|
||||
const Table *
|
||||
current_waveform_raw(float in_slew,
|
||||
float load_cap)
|
||||
{
|
||||
|
|
@ -501,14 +501,14 @@ current_waveform_raw(float in_slew,
|
|||
if (gate_model) {
|
||||
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
||||
if (waveforms) {
|
||||
const Table1 *waveform = waveforms->currentWaveformRaw(in_slew, load_cap);
|
||||
const Table *waveform = waveforms->currentWaveformRaw(in_slew, load_cap);
|
||||
return waveform;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Table1
|
||||
Table
|
||||
voltage_current_waveform(float in_slew,
|
||||
float load_cap)
|
||||
{
|
||||
|
|
@ -516,11 +516,11 @@ voltage_current_waveform(float in_slew,
|
|||
if (gate_model) {
|
||||
OutputWaveforms *waveforms = gate_model->outputWaveforms();
|
||||
if (waveforms) {
|
||||
Table1 waveform = waveforms->voltageCurrentWaveform(in_slew, load_cap);
|
||||
Table waveform = waveforms->voltageCurrentWaveform(in_slew, load_cap);
|
||||
return waveform;
|
||||
}
|
||||
}
|
||||
return Table1();
|
||||
return Table();
|
||||
}
|
||||
|
||||
float
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@
|
|||
#include "TimingArc.hh"
|
||||
#include "TimingModel.hh"
|
||||
#include "TableModel.hh"
|
||||
#include "InternalPower.hh"
|
||||
#include "LeakagePower.hh"
|
||||
#include "Sequential.hh"
|
||||
#include "Liberty.hh"
|
||||
|
||||
|
|
@ -263,28 +261,24 @@ LibertyBuilder::makeTimingArcs(LibertyCell *cell,
|
|||
attrs);
|
||||
case TimingType::non_seq_setup_rising:
|
||||
return makeFromTransitionArcs(cell, from_port, to_port, related_out,
|
||||
RiseFall::rise(),
|
||||
TimingRole::nonSeqSetup(), attrs);
|
||||
RiseFall::rise(), TimingRole::nonSeqSetup(),
|
||||
attrs);
|
||||
case TimingType::non_seq_setup_falling:
|
||||
return makeFromTransitionArcs(cell, from_port, to_port, related_out,
|
||||
RiseFall::fall(),
|
||||
TimingRole::nonSeqSetup(), attrs);
|
||||
RiseFall::fall(), TimingRole::nonSeqSetup(),
|
||||
attrs);
|
||||
case TimingType::non_seq_hold_rising:
|
||||
return makeFromTransitionArcs(cell, from_port, to_port, related_out,
|
||||
RiseFall::rise(),
|
||||
TimingRole::nonSeqHold(),
|
||||
RiseFall::rise(), TimingRole::nonSeqHold(),
|
||||
attrs);
|
||||
case TimingType::non_seq_hold_falling:
|
||||
return makeFromTransitionArcs(cell, from_port, to_port, related_out,
|
||||
RiseFall::fall(),
|
||||
TimingRole::nonSeqHold(),
|
||||
RiseFall::fall(), TimingRole::nonSeqHold(),
|
||||
attrs);
|
||||
case TimingType::min_clock_tree_path:
|
||||
return makeClockTreePathArcs(cell, to_port, TimingRole::clockTreePathMin(),
|
||||
MinMax::min(), attrs);
|
||||
return makeClockTreePathArcs(cell, to_port, TimingRole::clockTreePathMin(), attrs);
|
||||
case TimingType::max_clock_tree_path:
|
||||
return makeClockTreePathArcs(cell, to_port, TimingRole::clockTreePathMax(),
|
||||
MinMax::max(), attrs);
|
||||
return makeClockTreePathArcs(cell, to_port, TimingRole::clockTreePathMax(), attrs);
|
||||
case TimingType::min_pulse_width:
|
||||
return makeMinPulseWidthArcs(cell, from_port, to_port, related_out,
|
||||
TimingRole::width(), attrs);
|
||||
|
|
@ -652,30 +646,24 @@ TimingArcSet *
|
|||
LibertyBuilder::makeClockTreePathArcs(LibertyCell *cell,
|
||||
LibertyPort *to_port,
|
||||
const TimingRole *role,
|
||||
const MinMax *min_max,
|
||||
TimingArcAttrsPtr attrs)
|
||||
{
|
||||
TimingArcSet *arc_set = makeTimingArcSet(cell, nullptr, to_port, role, attrs);
|
||||
for (auto to_rf : RiseFall::range()) {
|
||||
for (const RiseFall *to_rf : RiseFall::range()) {
|
||||
TimingModel *model = attrs->model(to_rf);
|
||||
if (model) {
|
||||
const GateTableModel *gate_model = dynamic_cast<GateTableModel *>(model);
|
||||
const RiseFall *opp_rf = to_rf->opposite();
|
||||
switch (attrs->timingSense()) {
|
||||
case TimingSense::positive_unate:
|
||||
makeTimingArc(arc_set, to_rf, to_rf, model);
|
||||
to_port->setClkTreeDelay(gate_model->delayModel(), to_rf, to_rf, min_max);
|
||||
break;
|
||||
case TimingSense::negative_unate:
|
||||
makeTimingArc(arc_set, opp_rf, to_rf, model);
|
||||
to_port->setClkTreeDelay(gate_model->delayModel(), opp_rf, to_rf, min_max);
|
||||
break;
|
||||
case TimingSense::non_unate:
|
||||
case TimingSense::unknown:
|
||||
makeTimingArc(arc_set, to_rf, to_rf, model);
|
||||
makeTimingArc(arc_set, opp_rf, to_rf, model);
|
||||
to_port->setClkTreeDelay(gate_model->delayModel(), to_rf, to_rf, min_max);
|
||||
to_port->setClkTreeDelay(gate_model->delayModel(), opp_rf, to_rf, min_max);
|
||||
break;
|
||||
case TimingSense::none:
|
||||
break;
|
||||
|
|
@ -714,7 +702,7 @@ LibertyBuilder::makeTimingArcSet(LibertyCell *cell,
|
|||
const TimingRole *role,
|
||||
TimingArcAttrsPtr attrs)
|
||||
{
|
||||
return new TimingArcSet(cell, from, to, nullptr, role, attrs);
|
||||
return cell->makeTimingArcSet(from, to, nullptr, role, attrs);
|
||||
}
|
||||
|
||||
TimingArcSet *
|
||||
|
|
@ -725,7 +713,7 @@ LibertyBuilder::makeTimingArcSet(LibertyCell *cell,
|
|||
const TimingRole *role,
|
||||
TimingArcAttrsPtr attrs)
|
||||
{
|
||||
return new TimingArcSet(cell, from, to, related_out, role, attrs);
|
||||
return cell->makeTimingArcSet(from, to, related_out, role, attrs);
|
||||
}
|
||||
|
||||
TimingArc *
|
||||
|
|
@ -747,15 +735,4 @@ LibertyBuilder::makeTimingArc(TimingArcSet *set,
|
|||
return new TimingArc(set, from_rf, to_rf, model);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
InternalPower *
|
||||
LibertyBuilder::makeInternalPower(LibertyCell *cell,
|
||||
LibertyPort *port,
|
||||
LibertyPort *related_port,
|
||||
InternalPowerAttrs *attrs)
|
||||
{
|
||||
return new InternalPower(cell, port, related_port, attrs);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -32,8 +32,6 @@
|
|||
namespace sta {
|
||||
|
||||
class TimingArcAttrs;
|
||||
class InternalPowerAttrs;
|
||||
class LeakagePowerAttrs;
|
||||
class Debug;
|
||||
class Report;
|
||||
|
||||
|
|
@ -66,11 +64,6 @@ public:
|
|||
LibertyPort *related_out,
|
||||
TimingArcAttrsPtr attrs,
|
||||
int line);
|
||||
InternalPower *makeInternalPower(LibertyCell *cell,
|
||||
LibertyPort *port,
|
||||
LibertyPort *related_port,
|
||||
InternalPowerAttrs *attrs);
|
||||
|
||||
TimingArcSet *makeFromTransitionArcs(LibertyCell *cell,
|
||||
LibertyPort *from_port,
|
||||
LibertyPort *to_port,
|
||||
|
|
@ -87,7 +80,6 @@ public:
|
|||
TimingArcSet *makeClockTreePathArcs(LibertyCell *cell,
|
||||
LibertyPort *to_port,
|
||||
const TimingRole *role,
|
||||
const MinMax *min_max,
|
||||
TimingArcAttrsPtr attrs);
|
||||
TimingArcSet *makeMinPulseWidthArcs(LibertyCell *cell,
|
||||
LibertyPort *from_port,
|
||||
|
|
|
|||
|
|
@ -61,6 +61,11 @@ class BigcoCell : public LibertyCell
|
|||
public:
|
||||
BigcoCell(LibertyLibrary *library, const char *name, const char *filename);
|
||||
void setThingy(const char *thingy);
|
||||
TimingArcSet *makeTimingArcSet(LibertyPort *from,
|
||||
LibertyPort *to,
|
||||
LibertyPort *related_out,
|
||||
const TimingRole *role,
|
||||
TimingArcAttrsPtr attrs) override;
|
||||
|
||||
protected:
|
||||
const char *thingy_;
|
||||
|
|
@ -79,6 +84,28 @@ BigcoCell::setThingy(const char *thingy)
|
|||
thingy_ = thingy;
|
||||
}
|
||||
|
||||
TimingArcSet *
|
||||
BigcoCell::makeTimingArcSet(LibertyPort *from,
|
||||
LibertyPort *to,
|
||||
LibertyPort *related_out,
|
||||
const TimingRole *role,
|
||||
TimingArcAttrsPtr attrs)
|
||||
{
|
||||
size_t set_index = timing_arc_sets_.size();
|
||||
TimingArcSet *arc_set = new BigcoTimingArcSet(this, from, to, related_out,
|
||||
role, attrs, set_index);
|
||||
timing_arc_sets_.push_back(arc_set);
|
||||
|
||||
if (role == TimingRole::regClkToQ()
|
||||
|| role == TimingRole::latchEnToQ()) {
|
||||
from->setIsRegClk(true);
|
||||
to->setIsRegOutput(true);
|
||||
}
|
||||
if (role->isTimingCheck())
|
||||
from->setIsCheckClk(true);
|
||||
return arc_set;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
class BigcoTimingGroup : public TimingGroup
|
||||
|
|
@ -109,21 +136,22 @@ BigcoTimingGroup::setFrob(const char *frob)
|
|||
class BigcoTimingArcSet : public TimingArcSet
|
||||
{
|
||||
public:
|
||||
BigcoTimingArcSet(LibertyCell *cell, LibertyPort *from, LibertyPort *to,
|
||||
LibertyPort *related_out, TimingRole *role,
|
||||
TimingArcAttrs *attrs);
|
||||
BigcoTimingArcSet(LibertyCell *cell, LibertyPort *from, LibertyPort *to,
|
||||
LibertyPort *related_out, const TimingRole *role,
|
||||
TimingArcAttrsPtr attrs, size_t index);
|
||||
|
||||
protected:
|
||||
const char *frob_;
|
||||
};
|
||||
|
||||
BigcoTimingArcSet::BigcoTimingArcSet(LibertyCell *cell, LibertyPort *from,
|
||||
LibertyPort *to,
|
||||
LibertyPort *related_out, TimingRole *role,
|
||||
TimingArcAttrs *attrs) :
|
||||
TimingArcSet(cell, from, to, related_out, role, attrs)
|
||||
BigcoTimingArcSet::BigcoTimingArcSet(LibertyCell *cell, LibertyPort *from,
|
||||
LibertyPort *to,
|
||||
LibertyPort *related_out,
|
||||
const TimingRole *role,
|
||||
TimingArcAttrsPtr attrs, size_t index) :
|
||||
TimingArcSet(cell, from, to, related_out, role, attrs, index)
|
||||
{
|
||||
const char *frob = static_cast<BigcoTimingGroup*>(attrs)->frob();
|
||||
const char *frob = static_cast<BigcoTimingGroup*>(attrs.get())->frob();
|
||||
if (frob)
|
||||
frob_ = stringCopy(frob);
|
||||
}
|
||||
|
|
@ -138,11 +166,11 @@ public:
|
|||
const char *filename);
|
||||
|
||||
protected:
|
||||
virtual TimingArcSet *makeTimingArcSet(LibertyCell *cell, LibertyPort *from,
|
||||
LibertyPort *to,
|
||||
virtual TimingArcSet *makeTimingArcSet(LibertyCell *cell, LibertyPort *from,
|
||||
LibertyPort *to,
|
||||
LibertyPort *related_out,
|
||||
TimingRole *role,
|
||||
TimingArcAttrs *attrs);
|
||||
const TimingRole *role,
|
||||
TimingArcAttrsPtr attrs) override;
|
||||
};
|
||||
|
||||
LibertyCell *
|
||||
|
|
@ -155,13 +183,13 @@ BigcoLibertyBuilder::makeCell(LibertyLibrary *library, const char *name,
|
|||
}
|
||||
|
||||
TimingArcSet *
|
||||
BigcoLibertyBuilder::makeTimingArcSet(LibertyCell *cell, LibertyPort *from,
|
||||
LibertyPort *to,
|
||||
BigcoLibertyBuilder::makeTimingArcSet(LibertyCell *cell, LibertyPort *from,
|
||||
LibertyPort *to,
|
||||
LibertyPort *related_out,
|
||||
TimingRole *role,
|
||||
TimingArcAttrs *attrs)
|
||||
const TimingRole *role,
|
||||
TimingArcAttrsPtr attrs)
|
||||
{
|
||||
return new BigcoTimingArcSet(cell, from, to, related_out, role, attrs);
|
||||
return cell->makeTimingArcSet(from, to, related_out, role, attrs);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -87,14 +87,14 @@ EOL \r?\n
|
|||
{FLOAT}{TOKEN_END} {
|
||||
/* Push back the TOKEN_END character. */
|
||||
yyless(yyleng - 1);
|
||||
yylval->number = strtod(yytext, nullptr);
|
||||
yylval->emplace<float>(strtod(yytext, nullptr));
|
||||
return token::FLOAT;
|
||||
}
|
||||
|
||||
{ALPHA}({ALPHA}|_|{DIGIT})*{TOKEN_END} {
|
||||
/* Push back the TOKEN_END character. */
|
||||
yyless(yyleng - 1);
|
||||
yylval->string = sta::stringCopy(yytext);
|
||||
yylval->emplace<std::string>(yytext);
|
||||
return token::KEYWORD;
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ EOL \r?\n
|
|||
{TOKEN}{TOKEN_END} {
|
||||
/* Push back the TOKEN_END character. */
|
||||
yyless(yyleng - 1);
|
||||
yylval->string = sta::stringCopy(yytext);
|
||||
yylval->emplace<std::string>(yytext);
|
||||
return token::STRING;
|
||||
}
|
||||
|
||||
|
|
@ -134,14 +134,14 @@ EOL \r?\n
|
|||
|
||||
<qstring>\" {
|
||||
BEGIN(INITIAL);
|
||||
yylval->string = stringCopy(token_.c_str());
|
||||
yylval->emplace<std::string>(token_);
|
||||
return token::STRING;
|
||||
}
|
||||
|
||||
<qstring>{EOL} {
|
||||
error("unterminated string constant");
|
||||
BEGIN(INITIAL);
|
||||
yylval->string = stringCopy(token_.c_str());
|
||||
yylval->emplace<std::string>(token_);
|
||||
return token::STRING;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@
|
|||
|
||||
%{
|
||||
#include <cstdlib>
|
||||
#include <variant>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "Report.hh"
|
||||
#include "liberty/LibertyParser.hh"
|
||||
|
|
@ -57,32 +60,23 @@ sta::LibertyParse::error(const location_type &loc,
|
|||
%parse-param { LibertyScanner *scanner }
|
||||
%parse-param { LibertyParser *reader }
|
||||
%define api.parser.class {LibertyParse}
|
||||
%define api.value.type variant
|
||||
|
||||
%expect 2
|
||||
|
||||
%union {
|
||||
char *string;
|
||||
float number;
|
||||
char ch;
|
||||
sta::LibertyAttrValue *attr_value;
|
||||
sta::LibertyAttrValueSeq *attr_values;
|
||||
sta::LibertyGroup *group;
|
||||
sta::LibertyStmt *stmt;
|
||||
}
|
||||
%token <std::string> STRING KEYWORD
|
||||
%token <float> FLOAT
|
||||
|
||||
%left '+' '-' '|'
|
||||
%left '*' '/' '&'
|
||||
%left '^'
|
||||
%left '!'
|
||||
|
||||
%token <number> FLOAT
|
||||
%token <string> STRING KEYWORD
|
||||
|
||||
%type <stmt> statement complex_attr simple_attr variable group file
|
||||
%type <attr_values> attr_values
|
||||
%type <attr_value> attr_value
|
||||
%type <string> string expr expr_term expr_term1 volt_expr
|
||||
%type <ch> expr_op volt_op
|
||||
%type <sta::LibertyStmt *> statement complex_attr simple_attr variable group file
|
||||
%type <sta::LibertyAttrValueSeq *> attr_values
|
||||
%type <sta::LibertyAttrValue *> attr_value
|
||||
%type <std::string> string expr expr_term expr_term1 volt_expr
|
||||
%type <char> expr_op volt_op
|
||||
|
||||
%start file
|
||||
|
||||
|
|
@ -94,19 +88,19 @@ file:
|
|||
|
||||
group:
|
||||
KEYWORD '(' ')' '{'
|
||||
{ reader->groupBegin($1, nullptr, loc_line(@1)); }
|
||||
{ reader->groupBegin(std::move($1), nullptr, loc_line(@1)); }
|
||||
'}' semi_opt
|
||||
{ $$ = reader->groupEnd(); }
|
||||
| KEYWORD '(' ')' '{'
|
||||
{ reader->groupBegin($1, nullptr, loc_line(@1)); }
|
||||
{ reader->groupBegin(std::move($1), nullptr, loc_line(@1)); }
|
||||
statements '}' semi_opt
|
||||
{ $$ = reader->groupEnd(); }
|
||||
| KEYWORD '(' attr_values ')' '{'
|
||||
{ reader->groupBegin($1, $3, loc_line(@1)); }
|
||||
{ reader->groupBegin(std::move($1), $3, loc_line(@1)); }
|
||||
'}' semi_opt
|
||||
{ $$ = reader->groupEnd(); }
|
||||
| KEYWORD '(' attr_values ')' '{'
|
||||
{ reader->groupBegin($1, $3, loc_line(@1)); }
|
||||
{ reader->groupBegin(std::move($1), $3, loc_line(@1)); }
|
||||
statements '}' semi_opt
|
||||
{ $$ = reader->groupEnd(); }
|
||||
;
|
||||
|
|
@ -125,14 +119,14 @@ statement:
|
|||
|
||||
simple_attr:
|
||||
KEYWORD ':' attr_value semi_opt
|
||||
{ $$ = reader->makeSimpleAttr($1, $3, loc_line(@1)); }
|
||||
{ $$ = reader->makeSimpleAttr(std::move($1), $3, loc_line(@1)); }
|
||||
;
|
||||
|
||||
complex_attr:
|
||||
KEYWORD '(' ')' semi_opt
|
||||
{ $$ = reader->makeComplexAttr($1, nullptr, loc_line(@1)); }
|
||||
{ $$ = reader->makeComplexAttr(std::move($1), nullptr, loc_line(@1)); }
|
||||
| KEYWORD '(' attr_values ')' semi_opt
|
||||
{ $$ = reader->makeComplexAttr($1, $3, loc_line(@1)); }
|
||||
{ $$ = reader->makeComplexAttr(std::move($1), $3, loc_line(@1)); }
|
||||
;
|
||||
|
||||
attr_values:
|
||||
|
|
@ -152,7 +146,7 @@ attr_values:
|
|||
|
||||
variable:
|
||||
string '=' FLOAT semi_opt
|
||||
{ $$ = reader->makeVariable($1, $3, loc_line(@1)); }
|
||||
{ $$ = reader->makeVariable(std::move($1), $3, loc_line(@1)); }
|
||||
;
|
||||
|
||||
string:
|
||||
|
|
@ -166,28 +160,22 @@ attr_value:
|
|||
FLOAT
|
||||
{ $$ = reader->makeFloatAttrValue($1); }
|
||||
| expr
|
||||
{ $$ = reader->makeStringAttrValue($1); }
|
||||
{ $$ = reader->makeStringAttrValue(std::move($1)); }
|
||||
| volt_expr
|
||||
{ $$ = reader->makeStringAttrValue($1); }
|
||||
{ $$ = reader->makeStringAttrValue(std::move($1)); }
|
||||
;
|
||||
|
||||
/* Voltage expressions are ignored. */
|
||||
/* Crafted to avoid conflicts with expr */
|
||||
volt_expr:
|
||||
FLOAT volt_op FLOAT
|
||||
{ $$ = sta::stringPrint("%e%c%e", $1, $2, $3); }
|
||||
{ $$ = sta::stdstrPrint("%e%c%e", $1, $2, $3); }
|
||||
| string volt_op FLOAT
|
||||
{ $$ = sta::stringPrint("%s%c%e", $1, $2, $3);
|
||||
sta::stringDelete($1);
|
||||
}
|
||||
{ $$ = sta::stdstrPrint("%s%c%e", $1.c_str(), $2, $3); }
|
||||
| FLOAT volt_op string
|
||||
{ $$ = sta::stringPrint("%e%c%s", $1, $2, $3);
|
||||
sta::stringDelete($3);
|
||||
}
|
||||
{ $$ = sta::stdstrPrint("%e%c%s", $1, $2, $3.c_str()); }
|
||||
| volt_expr volt_op FLOAT
|
||||
{ $$ = sta::stringPrint("%s%c%e", $1, $2, $3);
|
||||
sta::stringDelete($1);
|
||||
}
|
||||
{ $$ = sta::stdstrPrint("%s%c%e", $1.c_str(), $2, $3); }
|
||||
;
|
||||
|
||||
volt_op:
|
||||
|
|
@ -204,34 +192,25 @@ volt_op:
|
|||
expr:
|
||||
expr_term1
|
||||
| expr_term1 expr_op expr
|
||||
{ $$ = sta::stringPrint("%s%c%s", $1, $2, $3);
|
||||
sta::stringDelete($1);
|
||||
sta::stringDelete($3);
|
||||
}
|
||||
{ $$ = sta::stdstrPrint("%s%c%s", $1.c_str(), $2, $3.c_str()); }
|
||||
;
|
||||
|
||||
expr_term:
|
||||
string
|
||||
| '0'
|
||||
{ $$ = sta::stringPrint("0"); }
|
||||
{ $$ = std::string("0"); }
|
||||
| '1'
|
||||
{ $$ = sta::stringPrint("1"); }
|
||||
{ $$ = std::string("1"); }
|
||||
| '(' expr ')'
|
||||
{ $$ = sta::stringPrint("(%s)", $2);
|
||||
sta::stringDelete($2);
|
||||
}
|
||||
{ $$ = "(" + $2 + ")"; }
|
||||
;
|
||||
|
||||
expr_term1:
|
||||
expr_term
|
||||
| '!' expr_term
|
||||
{ $$ = sta::stringPrint("!%s", $2);
|
||||
sta::stringDelete($2);
|
||||
}
|
||||
{ $$ = "!" + $2; }
|
||||
| expr_term '\''
|
||||
{ $$ = sta::stringPrint("%s'", $1);
|
||||
sta::stringDelete($1);
|
||||
}
|
||||
{ $$ = $1 + "'"; }
|
||||
;
|
||||
|
||||
expr_op:
|
||||
|
|
|
|||
|
|
@ -76,15 +76,15 @@ LibertyParser::makeDefine(LibertyAttrValueSeq *values,
|
|||
{
|
||||
LibertyDefine *define = nullptr;
|
||||
if (values->size() == 3) {
|
||||
const char *define_name = (*values)[0]->stringValue();
|
||||
const char *group_type_name = (*values)[1]->stringValue();
|
||||
const char *value_type_name = (*values)[2]->stringValue();
|
||||
LibertyAttrType value_type = attrValueType(value_type_name);
|
||||
LibertyGroupType group_type = groupType(group_type_name);
|
||||
define = new LibertyDefine(define_name, group_type,
|
||||
std::string define_name = (*values)[0]->stringValue();
|
||||
const std::string &group_type_name = (*values)[1]->stringValue();
|
||||
const std::string &value_type_name = (*values)[2]->stringValue();
|
||||
LibertyAttrType value_type = attrValueType(value_type_name.c_str());
|
||||
LibertyGroupType group_type = groupType(group_type_name.c_str());
|
||||
define = new LibertyDefine(std::move(define_name), group_type,
|
||||
value_type, line);
|
||||
LibertyGroup *group = this->group();
|
||||
group->addDefine(define);
|
||||
group->addStmt(define);
|
||||
}
|
||||
else
|
||||
report_->fileWarn(24, filename_.c_str(), line,
|
||||
|
|
@ -126,12 +126,11 @@ LibertyParser::groupType(const char *group_type_name)
|
|||
}
|
||||
|
||||
void
|
||||
LibertyParser::groupBegin(const char *type,
|
||||
LibertyParser::groupBegin(std::string type,
|
||||
LibertyAttrValueSeq *params,
|
||||
int line)
|
||||
{
|
||||
LibertyGroup *group = new LibertyGroup(type, params, line);
|
||||
stringDelete(type);
|
||||
LibertyGroup *group = new LibertyGroup(std::move(type), params, line);
|
||||
group_visitor_->begin(group);
|
||||
group_stack_.push_back(group);
|
||||
}
|
||||
|
|
@ -145,9 +144,11 @@ LibertyParser::groupEnd()
|
|||
LibertyGroup *parent =
|
||||
group_stack_.empty() ? nullptr : group_stack_.back();
|
||||
if (parent && group_visitor_->save(group)) {
|
||||
parent->addSubgroup(group);
|
||||
parent->addStmt(group);
|
||||
return group;
|
||||
}
|
||||
else if (group_visitor_->save(group))
|
||||
return group;
|
||||
else {
|
||||
delete group;
|
||||
return nullptr;
|
||||
|
|
@ -167,16 +168,15 @@ LibertyParser::deleteGroups()
|
|||
}
|
||||
|
||||
LibertyStmt *
|
||||
LibertyParser::makeSimpleAttr(const char *name,
|
||||
LibertyParser::makeSimpleAttr(std::string name,
|
||||
LibertyAttrValue *value,
|
||||
int line)
|
||||
{
|
||||
LibertyAttr *attr = new LibertySimpleAttr(name, value, line);
|
||||
stringDelete(name);
|
||||
LibertyAttr *attr = new LibertySimpleAttr(std::move(name), value, line);
|
||||
group_visitor_->visitAttr(attr);
|
||||
LibertyGroup *group = this->group();
|
||||
if (group && group_visitor_->save(attr)) {
|
||||
group->addAttribute(attr);
|
||||
group->addStmt(attr);
|
||||
return attr;
|
||||
}
|
||||
else {
|
||||
|
|
@ -186,26 +186,24 @@ LibertyParser::makeSimpleAttr(const char *name,
|
|||
}
|
||||
|
||||
LibertyStmt *
|
||||
LibertyParser::makeComplexAttr(const char *name,
|
||||
LibertyParser::makeComplexAttr(std::string name,
|
||||
LibertyAttrValueSeq *values,
|
||||
int line)
|
||||
{
|
||||
// Defines have the same syntax as complex attributes.
|
||||
// Detect and convert them.
|
||||
if (stringEq(name, "define")) {
|
||||
if (name == "define") {
|
||||
LibertyStmt *define = makeDefine(values, line);
|
||||
stringDelete(name);
|
||||
deleteContents(values);
|
||||
delete values;
|
||||
return define;
|
||||
}
|
||||
else {
|
||||
LibertyAttr *attr = new LibertyComplexAttr(name, values, line);
|
||||
stringDelete(name);
|
||||
LibertyAttr *attr = new LibertyComplexAttr(std::move(name), values, line);
|
||||
group_visitor_->visitAttr(attr);
|
||||
if (group_visitor_->save(attr)) {
|
||||
LibertyGroup *group = this->group();
|
||||
group->addAttribute(attr);
|
||||
group->addStmt(attr);
|
||||
return attr;
|
||||
}
|
||||
delete attr;
|
||||
|
|
@ -214,12 +212,11 @@ LibertyParser::makeComplexAttr(const char *name,
|
|||
}
|
||||
|
||||
LibertyStmt *
|
||||
LibertyParser::makeVariable(const char *var,
|
||||
LibertyParser::makeVariable(std::string var,
|
||||
float value,
|
||||
int line)
|
||||
{
|
||||
LibertyVariable *variable = new LibertyVariable(var, value, line);
|
||||
stringDelete(var);
|
||||
LibertyVariable *variable = new LibertyVariable(std::move(var), value, line);
|
||||
group_visitor_->visitVariable(variable);
|
||||
if (group_visitor_->save(variable))
|
||||
return variable;
|
||||
|
|
@ -230,11 +227,9 @@ LibertyParser::makeVariable(const char *var,
|
|||
}
|
||||
|
||||
LibertyAttrValue *
|
||||
LibertyParser::makeStringAttrValue(char *value)
|
||||
LibertyParser::makeStringAttrValue(std::string value)
|
||||
{
|
||||
LibertyAttrValue *attr = new LibertyStringAttrValue(value);
|
||||
stringDelete(value);
|
||||
return attr;
|
||||
return new LibertyStringAttrValue(std::move(value));
|
||||
}
|
||||
|
||||
LibertyAttrValue *
|
||||
|
|
@ -243,6 +238,14 @@ LibertyParser::makeFloatAttrValue(float value)
|
|||
return new LibertyFloatAttrValue(value);
|
||||
}
|
||||
|
||||
const std::string &
|
||||
LibertyFloatAttrValue::stringValue() const
|
||||
{
|
||||
criticalError(1127, "LibertyStringAttrValue called for float value");
|
||||
static std::string null;
|
||||
return null;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
LibertyStmt::LibertyStmt(int line) :
|
||||
|
|
@ -250,49 +253,22 @@ LibertyStmt::LibertyStmt(int line) :
|
|||
{
|
||||
}
|
||||
|
||||
LibertyGroup::LibertyGroup(const char *type,
|
||||
LibertyGroup::LibertyGroup(std::string type,
|
||||
LibertyAttrValueSeq *params,
|
||||
int line) :
|
||||
LibertyStmt(line),
|
||||
type_(type),
|
||||
type_(std::move(type)),
|
||||
params_(params),
|
||||
attrs_(nullptr),
|
||||
attr_map_(nullptr),
|
||||
subgroups_(nullptr),
|
||||
define_map_(nullptr)
|
||||
stmts_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LibertyGroup::addSubgroup(LibertyGroup *subgroup)
|
||||
LibertyGroup::addStmt(LibertyStmt *stmt)
|
||||
{
|
||||
if (subgroups_ == nullptr)
|
||||
subgroups_ = new LibertyGroupSeq;
|
||||
subgroups_->push_back(subgroup);
|
||||
}
|
||||
|
||||
void
|
||||
LibertyGroup::addDefine(LibertyDefine *define)
|
||||
{
|
||||
if (define_map_ == nullptr)
|
||||
define_map_ = new LibertyDefineMap;
|
||||
const char *define_name = define->name();
|
||||
LibertyDefine *prev_define = findKey(define_map_, define_name);
|
||||
if (prev_define) {
|
||||
define_map_->erase(define_name);
|
||||
delete prev_define;
|
||||
}
|
||||
(*define_map_)[define_name] = define;
|
||||
}
|
||||
|
||||
void
|
||||
LibertyGroup::addAttribute(LibertyAttr *attr)
|
||||
{
|
||||
if (attrs_ == nullptr)
|
||||
attrs_ = new LibertyAttrSeq;
|
||||
attrs_->push_back(attr);
|
||||
if (attr_map_)
|
||||
(*attr_map_)[attr->name()] = attr;
|
||||
if (stmts_ == nullptr)
|
||||
stmts_ = new LibertyStmtSeq;
|
||||
stmts_->push_back(stmt);
|
||||
}
|
||||
|
||||
LibertyGroup::~LibertyGroup()
|
||||
|
|
@ -301,18 +277,9 @@ LibertyGroup::~LibertyGroup()
|
|||
deleteContents(params_);
|
||||
delete params_;
|
||||
}
|
||||
if (attrs_) {
|
||||
deleteContents(attrs_);
|
||||
delete attrs_;
|
||||
delete attr_map_;
|
||||
}
|
||||
if (subgroups_) {
|
||||
deleteContents(subgroups_);
|
||||
delete subgroups_;
|
||||
}
|
||||
if (define_map_) {
|
||||
deleteContents(define_map_);
|
||||
delete define_map_;
|
||||
if (stmts_) {
|
||||
deleteContents(stmts_);
|
||||
delete stmts_;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -322,7 +289,7 @@ LibertyGroup::firstName()
|
|||
if (params_ && params_->size() > 0) {
|
||||
LibertyAttrValue *value = (*params_)[0];
|
||||
if (value->isString())
|
||||
return value->stringValue();
|
||||
return value->stringValue().c_str();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -333,39 +300,24 @@ LibertyGroup::secondName()
|
|||
if (params_ && params_->size() > 1) {
|
||||
LibertyAttrValue *value = (*params_)[1];
|
||||
if (value->isString())
|
||||
return value->stringValue();
|
||||
return value->stringValue().c_str();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LibertyAttr *
|
||||
LibertyGroup::findAttr(const char *name)
|
||||
{
|
||||
if (attrs_) {
|
||||
if (attr_map_ == nullptr) {
|
||||
// Build attribute name map on demand.
|
||||
for (LibertyAttr *attr : *attrs_)
|
||||
(*attr_map_)[attr->name()] = attr;
|
||||
}
|
||||
return findKey(attr_map_, name);
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
LibertyAttr::LibertyAttr(const char *name,
|
||||
LibertyAttr::LibertyAttr(std::string name,
|
||||
int line) :
|
||||
LibertyStmt(line),
|
||||
name_(name)
|
||||
name_(std::move(name))
|
||||
{
|
||||
}
|
||||
|
||||
LibertySimpleAttr::LibertySimpleAttr(const char *name,
|
||||
LibertySimpleAttr::LibertySimpleAttr(std::string name,
|
||||
LibertyAttrValue *value,
|
||||
int line) :
|
||||
LibertyAttr(name, line),
|
||||
LibertyAttr(std::move(name), line),
|
||||
value_(value)
|
||||
{
|
||||
}
|
||||
|
|
@ -382,10 +334,12 @@ LibertySimpleAttr::values() const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
LibertyComplexAttr::LibertyComplexAttr(const char *name,
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
LibertyComplexAttr::LibertyComplexAttr(std::string name,
|
||||
LibertyAttrValueSeq *values,
|
||||
int line) :
|
||||
LibertyAttr(name, line),
|
||||
LibertyAttr(std::move(name), line),
|
||||
values_(values)
|
||||
{
|
||||
}
|
||||
|
|
@ -407,9 +361,9 @@ LibertyComplexAttr::firstValue()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
LibertyStringAttrValue::LibertyStringAttrValue(const char *value) :
|
||||
LibertyStringAttrValue::LibertyStringAttrValue(std::string value) :
|
||||
LibertyAttrValue(),
|
||||
value_(value)
|
||||
value_(std::move(value))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -420,38 +374,19 @@ LibertyStringAttrValue::floatValue() const
|
|||
return 0.0;
|
||||
}
|
||||
|
||||
const char *
|
||||
LibertyStringAttrValue::stringValue() const
|
||||
{
|
||||
return value_.c_str();
|
||||
}
|
||||
|
||||
LibertyFloatAttrValue::LibertyFloatAttrValue(float value) :
|
||||
value_(value)
|
||||
{
|
||||
}
|
||||
|
||||
float
|
||||
LibertyFloatAttrValue::floatValue() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
const char *
|
||||
LibertyFloatAttrValue::stringValue() const
|
||||
{
|
||||
criticalError(1127, "LibertyStringAttrValue called for float value");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
LibertyDefine::LibertyDefine(const char *name,
|
||||
LibertyDefine::LibertyDefine(std::string name,
|
||||
LibertyGroupType group_type,
|
||||
LibertyAttrType value_type,
|
||||
int line) :
|
||||
LibertyStmt(line),
|
||||
name_(name),
|
||||
name_(std::move(name)),
|
||||
group_type_(group_type),
|
||||
value_type_(value_type)
|
||||
{
|
||||
|
|
@ -459,11 +394,11 @@ LibertyDefine::LibertyDefine(const char *name,
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
LibertyVariable::LibertyVariable(const char *var,
|
||||
LibertyVariable::LibertyVariable(std::string var,
|
||||
float value,
|
||||
int line) :
|
||||
LibertyStmt(line),
|
||||
var_(var),
|
||||
var_(std::move(var)),
|
||||
value_(value)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,15 +34,12 @@ namespace sta {
|
|||
|
||||
class Report;
|
||||
class LibertyGroupVisitor;
|
||||
class LibertyAttrVisitor;
|
||||
class LibertyStmt;
|
||||
class LibertyGroup;
|
||||
class LibertyAttr;
|
||||
class LibertyDefine;
|
||||
class LibertyAttrValue;
|
||||
class LibertyVariable;
|
||||
class LibertySubgroupIterator;
|
||||
class LibertyAttrIterator;
|
||||
class LibertyScanner;
|
||||
|
||||
using LibertyStmtSeq = std::vector<LibertyStmt*>;
|
||||
|
|
@ -72,21 +69,21 @@ public:
|
|||
int line);
|
||||
LibertyAttrType attrValueType(const char *value_type_name);
|
||||
LibertyGroupType groupType(const char *group_type_name);
|
||||
void groupBegin(const char *type,
|
||||
void groupBegin(std::string type,
|
||||
LibertyAttrValueSeq *params,
|
||||
int line);
|
||||
LibertyGroup *groupEnd();
|
||||
LibertyGroup *group();
|
||||
void deleteGroups();
|
||||
LibertyStmt *makeSimpleAttr(const char *name,
|
||||
LibertyStmt *makeSimpleAttr(std::string name,
|
||||
LibertyAttrValue *value,
|
||||
int line);
|
||||
LibertyStmt *makeComplexAttr(const char *name,
|
||||
LibertyStmt *makeComplexAttr(std::string name,
|
||||
LibertyAttrValueSeq *values,
|
||||
int line);
|
||||
LibertyAttrValue *makeStringAttrValue(char *value);
|
||||
LibertyAttrValue *makeStringAttrValue(std::string value);
|
||||
LibertyAttrValue *makeFloatAttrValue(float value);
|
||||
LibertyStmt *makeVariable(const char *var,
|
||||
LibertyStmt *makeVariable(std::string var,
|
||||
float value,
|
||||
int line);
|
||||
|
||||
|
|
@ -106,6 +103,8 @@ public:
|
|||
int line() const { return line_; }
|
||||
virtual bool isGroup() const { return false; }
|
||||
virtual bool isAttribute() const { return false; }
|
||||
virtual bool isSimpleAttr() const { return false; }
|
||||
virtual bool isComplexAttr() const { return false; }
|
||||
virtual bool isDefine() const { return false; }
|
||||
virtual bool isVariable() const { return false; }
|
||||
|
||||
|
|
@ -119,46 +118,35 @@ protected:
|
|||
class LibertyGroup : public LibertyStmt
|
||||
{
|
||||
public:
|
||||
LibertyGroup(const char *type,
|
||||
LibertyGroup(std::string type,
|
||||
LibertyAttrValueSeq *params,
|
||||
int line);
|
||||
virtual ~LibertyGroup();
|
||||
virtual bool isGroup() const { return true; }
|
||||
const char *type() const { return type_.c_str(); }
|
||||
const std::string &type() const { return type_; }
|
||||
LibertyAttrValueSeq *params() const { return params_; }
|
||||
// First param as a string.
|
||||
const char *firstName();
|
||||
// Second param as a string.
|
||||
const char *secondName();
|
||||
LibertyAttr *findAttr(const char *name);
|
||||
void addSubgroup(LibertyGroup *subgroup);
|
||||
void addDefine(LibertyDefine *define);
|
||||
void addAttribute(LibertyAttr *attr);
|
||||
void addVariable(LibertyVariable *var);
|
||||
LibertyGroupSeq *subgroups() const { return subgroups_; }
|
||||
LibertyAttrSeq *attrs() const { return attrs_; }
|
||||
LibertyAttrValueSeq *params() const { return params_; }
|
||||
void addStmt(LibertyStmt *stmt);
|
||||
LibertyStmtSeq *stmts() const { return stmts_; }
|
||||
|
||||
protected:
|
||||
void parseNames(LibertyAttrValueSeq *values);
|
||||
|
||||
std::string type_;
|
||||
LibertyAttrValueSeq *params_;
|
||||
LibertyAttrSeq *attrs_;
|
||||
LibertyAttrMap *attr_map_;
|
||||
LibertyGroupSeq *subgroups_;
|
||||
LibertyDefineMap *define_map_;
|
||||
LibertyStmtSeq *stmts_;
|
||||
};
|
||||
|
||||
// Abstract base class for attributes.
|
||||
class LibertyAttr : public LibertyStmt
|
||||
{
|
||||
public:
|
||||
LibertyAttr(const char *name,
|
||||
LibertyAttr(std::string name,
|
||||
int line);
|
||||
const char *name() const { return name_.c_str(); }
|
||||
virtual bool isAttribute() const { return true; }
|
||||
virtual bool isSimple() const = 0;
|
||||
virtual bool isComplex() const = 0;
|
||||
const std::string &name() const { return name_; }
|
||||
virtual LibertyAttrValueSeq *values() const = 0;
|
||||
virtual LibertyAttrValue *firstValue() = 0;
|
||||
|
||||
|
|
@ -171,12 +159,11 @@ protected:
|
|||
class LibertySimpleAttr : public LibertyAttr
|
||||
{
|
||||
public:
|
||||
LibertySimpleAttr(const char *name,
|
||||
LibertySimpleAttr(std::string name,
|
||||
LibertyAttrValue *value,
|
||||
int line);
|
||||
virtual ~LibertySimpleAttr();
|
||||
bool isSimple() const override { return true; };
|
||||
bool isComplex() const override { return false; };
|
||||
bool isSimpleAttr() const override { return true; };
|
||||
LibertyAttrValue *firstValue() override { return value_; };
|
||||
LibertyAttrValueSeq *values() const override;
|
||||
|
||||
|
|
@ -189,12 +176,11 @@ private:
|
|||
class LibertyComplexAttr : public LibertyAttr
|
||||
{
|
||||
public:
|
||||
LibertyComplexAttr(const char *name,
|
||||
LibertyComplexAttr(std::string name,
|
||||
LibertyAttrValueSeq *values,
|
||||
int line);
|
||||
virtual ~LibertyComplexAttr();
|
||||
bool isSimple() const override { return false; }
|
||||
bool isComplex() const override { return true; }
|
||||
bool isComplexAttr() const override { return true; };
|
||||
LibertyAttrValue *firstValue() override ;
|
||||
LibertyAttrValueSeq *values() const override { return values_; }
|
||||
|
||||
|
|
@ -211,18 +197,18 @@ public:
|
|||
virtual bool isString() const = 0;
|
||||
virtual bool isFloat() const = 0;
|
||||
virtual float floatValue() const = 0;
|
||||
virtual const char *stringValue() const = 0;
|
||||
virtual const std::string &stringValue() const = 0;
|
||||
};
|
||||
|
||||
class LibertyStringAttrValue : public LibertyAttrValue
|
||||
{
|
||||
public:
|
||||
LibertyStringAttrValue(const char *value);
|
||||
LibertyStringAttrValue(std::string value);
|
||||
virtual ~LibertyStringAttrValue() {}
|
||||
bool isFloat() const override { return false; }
|
||||
bool isString() const override { return true; }
|
||||
float floatValue() const override ;
|
||||
const char *stringValue() const override;
|
||||
const std::string &stringValue() const override { return value_; }
|
||||
|
||||
private:
|
||||
std::string value_;
|
||||
|
|
@ -235,8 +221,8 @@ public:
|
|||
virtual ~LibertyFloatAttrValue() {}
|
||||
bool isString() const override { return false; }
|
||||
bool isFloat() const override { return true; }
|
||||
float floatValue() const override;
|
||||
const char *stringValue() const override;
|
||||
float floatValue() const override { return value_; }
|
||||
const std::string &stringValue() const override;
|
||||
|
||||
private:
|
||||
float value_;
|
||||
|
|
@ -248,12 +234,12 @@ private:
|
|||
class LibertyDefine : public LibertyStmt
|
||||
{
|
||||
public:
|
||||
LibertyDefine(const char *name,
|
||||
LibertyDefine(std::string name,
|
||||
LibertyGroupType group_type,
|
||||
LibertyAttrType value_type,
|
||||
int line);
|
||||
virtual bool isDefine() const { return true; }
|
||||
const char *name() const { return name_.c_str(); }
|
||||
const std::string &name() const { return name_; }
|
||||
LibertyGroupType groupType() const { return group_type_; }
|
||||
LibertyAttrType valueType() const { return value_type_; }
|
||||
|
||||
|
|
@ -270,11 +256,11 @@ private:
|
|||
class LibertyVariable : public LibertyStmt
|
||||
{
|
||||
public:
|
||||
LibertyVariable(const char *var,
|
||||
LibertyVariable(std::string var,
|
||||
float value,
|
||||
int line);
|
||||
bool isVariable() const override { return true; }
|
||||
const char *variable() const { return var_.c_str(); }
|
||||
const std::string &variable() const { return var_; }
|
||||
float value() const { return value_; }
|
||||
|
||||
private:
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -25,8 +25,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "StringSeq.hh"
|
||||
#include "MinMax.hh"
|
||||
|
|
@ -61,8 +62,8 @@ class OutputWaveform;
|
|||
|
||||
using LibraryAttrVisitor = void (LibertyReader::*)(LibertyAttr *attr);
|
||||
using LibraryGroupVisitor = void (LibertyReader::*)(LibertyGroup *group);
|
||||
using LibraryAttrMap = std::map<std::string, LibraryAttrVisitor>;
|
||||
using LibraryGroupMap = std::map<std::string ,LibraryGroupVisitor>;
|
||||
using LibraryAttrMap = std::unordered_map<std::string, LibraryAttrVisitor>;
|
||||
using LibraryGroupMap = std::unordered_map<std::string, LibraryGroupVisitor>;
|
||||
using PortGroupSeq = std::vector<PortGroup*>;
|
||||
using SequentialGroupSeq = std::vector<SequentialGroup*>;
|
||||
using LibertyFuncSeq = std::vector<LibertyFunc*>;
|
||||
|
|
@ -82,10 +83,12 @@ public:
|
|||
Network *network);
|
||||
virtual ~LibertyReader();
|
||||
virtual LibertyLibrary *readLibertyFile(const char *filename);
|
||||
LibertyLibrary *library() { return library_; }
|
||||
const LibertyLibrary *library() const { return library_; }
|
||||
|
||||
virtual void init(const char *filename,
|
||||
bool infer_latches,
|
||||
Network *network);
|
||||
LibertyLibrary *library() const { return library_; }
|
||||
virtual bool save(LibertyGroup *) { return false; }
|
||||
virtual bool save(LibertyAttr *) { return false; }
|
||||
virtual bool save(LibertyVariable *) { return false; }
|
||||
|
|
@ -384,10 +387,10 @@ public:
|
|||
virtual void endTable();
|
||||
virtual void makeTable(LibertyAttr *attr,
|
||||
float scale);
|
||||
virtual FloatTable *makeFloatTable(LibertyAttr *attr,
|
||||
size_t rows,
|
||||
size_t cols,
|
||||
float scale);
|
||||
virtual FloatTable makeFloatTable(LibertyAttr *attr,
|
||||
size_t rows,
|
||||
size_t cols,
|
||||
float scale);
|
||||
|
||||
virtual void beginLut(LibertyGroup *group);
|
||||
virtual void endLut(LibertyGroup *group);
|
||||
|
|
@ -408,7 +411,6 @@ public:
|
|||
virtual void endLeakagePower(LibertyGroup *group);
|
||||
virtual void beginInternalPower(LibertyGroup *group);
|
||||
virtual void endInternalPower(LibertyGroup *group);
|
||||
virtual InternalPowerGroup *makeInternalPowerGroup(int line);
|
||||
virtual void beginFallPower(LibertyGroup *group);
|
||||
virtual void beginRisePower(LibertyGroup *group);
|
||||
virtual void endRiseFallPower(LibertyGroup *group);
|
||||
|
|
@ -496,6 +498,8 @@ public:
|
|||
void endEcsmWaveform(LibertyGroup *group);
|
||||
LibertyPort *findPort(LibertyCell *cell,
|
||||
const char *port_name);
|
||||
virtual void begin(LibertyGroup *group);
|
||||
virtual void end(LibertyGroup *group);
|
||||
|
||||
protected:
|
||||
LibertyPort *makePort(LibertyCell *cell,
|
||||
|
|
@ -513,8 +517,6 @@ protected:
|
|||
int line);
|
||||
void setEnergyScale();
|
||||
void defineVisitors();
|
||||
virtual void begin(LibertyGroup *group);
|
||||
virtual void end(LibertyGroup *group);
|
||||
void defineGroupVisitor(const char *type,
|
||||
LibraryGroupVisitor begin_visitor,
|
||||
LibraryGroupVisitor end_visitor);
|
||||
|
|
@ -556,10 +558,9 @@ protected:
|
|||
float &value1,
|
||||
float &value2,
|
||||
bool &exists);
|
||||
void parseStringFloatList(const char *float_list,
|
||||
float scale,
|
||||
FloatSeq *values,
|
||||
LibertyAttr *attr);
|
||||
FloatSeq parseStringFloatList(const std::string &float_list,
|
||||
float scale,
|
||||
LibertyAttr *attr);
|
||||
LogicValue getAttrLogicValue(LibertyAttr *attr);
|
||||
void getAttrBool(LibertyAttr *attr,
|
||||
// Return values.
|
||||
|
|
@ -571,8 +572,8 @@ protected:
|
|||
LibertyAttr *attr);
|
||||
TableAxisPtr makeAxis(int index,
|
||||
LibertyGroup *group);
|
||||
FloatSeq *readFloatSeq(LibertyAttr *attr,
|
||||
float scale);
|
||||
FloatSeq readFloatSeq(LibertyAttr *attr,
|
||||
float scale);
|
||||
void variableValue(const char *var,
|
||||
float &value,
|
||||
bool &exists);
|
||||
|
|
@ -631,7 +632,7 @@ protected:
|
|||
bool in_ccsn_;
|
||||
bool in_ecsm_waveform_;
|
||||
TableAxisVariable axis_var_[3];
|
||||
FloatSeq *axis_values_[3];
|
||||
FloatSeq axis_values_[3];
|
||||
int type_bit_from_;
|
||||
bool type_bit_from_exists_;
|
||||
int type_bit_to_;
|
||||
|
|
@ -889,17 +890,45 @@ protected:
|
|||
ReceiverModelPtr receiver_model_;
|
||||
};
|
||||
|
||||
class InternalPowerGroup : public InternalPowerAttrs, public RelatedPortGroup
|
||||
class InternalPowerGroup : public RelatedPortGroup
|
||||
{
|
||||
public:
|
||||
InternalPowerGroup(int line);
|
||||
virtual ~InternalPowerGroup();
|
||||
const std::string &relatedPgPin() const { return related_pg_pin_; }
|
||||
void setRelatedPgPin(std::string related_pg_pin);
|
||||
const std::shared_ptr<FuncExpr> &when() const { return when_; }
|
||||
void setWhen(std::shared_ptr<FuncExpr> when);
|
||||
void setModel(const RiseFall *rf,
|
||||
std::shared_ptr<InternalPowerModel> model);
|
||||
InternalPowerModels &models() { return models_; }
|
||||
|
||||
private:
|
||||
std::string related_pg_pin_;
|
||||
std::shared_ptr<FuncExpr> when_;
|
||||
InternalPowerModels models_;
|
||||
};
|
||||
|
||||
class LeakagePowerGroup
|
||||
{
|
||||
public:
|
||||
LeakagePowerGroup(int line);
|
||||
<<<<<<<
|
||||
=======
|
||||
const std::string &relatedPgPin() const { return related_pg_pin_; }
|
||||
void setRelatedPgPin(std::string pin_name);
|
||||
FuncExpr *when() const { return when_; }
|
||||
void setWhen(FuncExpr *when);
|
||||
float power() const { return power_; }
|
||||
void setPower(float power);
|
||||
|
||||
protected:
|
||||
std::string related_pg_pin_;
|
||||
FuncExpr *when_;
|
||||
float power_;
|
||||
int line_;
|
||||
};
|
||||
|
||||
>>>>>>>
|
||||
const std::string &relatedPgPin() const { return related_pg_pin_; }
|
||||
void setRelatedPgPin(std::string pin_name);
|
||||
FuncExpr *when() const { return when_; }
|
||||
|
|
@ -953,19 +982,19 @@ class OutputWaveform
|
|||
public:
|
||||
OutputWaveform(float axis_value1,
|
||||
float axis_value2,
|
||||
Table1 *currents,
|
||||
Table *currents,
|
||||
float reference_time);
|
||||
~OutputWaveform();
|
||||
float slew() const { return slew_; }
|
||||
float cap() const { return cap_; }
|
||||
Table1 *currents() const { return currents_; }
|
||||
Table1 *stealCurrents();
|
||||
Table *currents() const { return currents_; }
|
||||
Table *stealCurrents();
|
||||
float referenceTime() { return reference_time_; }
|
||||
|
||||
private:
|
||||
float slew_;
|
||||
float cap_;
|
||||
Table1 *currents_;
|
||||
Table *currents_;
|
||||
float reference_time_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ LibertyWriter::writeTableTemplate(const TableTemplate *tbl_template)
|
|||
const TableAxis *axis3 = tbl_template->axis3();
|
||||
// skip scalar templates
|
||||
if (axis1) {
|
||||
fprintf(stream_, " lu_table_template(%s) {\n", tbl_template->name());
|
||||
fprintf(stream_, " lu_table_template(%s) {\n", tbl_template->name().c_str());
|
||||
fprintf(stream_, " variable_1 : %s;\n",
|
||||
tableVariableString(axis1->variable()));
|
||||
if (axis2)
|
||||
|
|
@ -227,11 +227,11 @@ LibertyWriter::writeTableTemplate(const TableTemplate *tbl_template)
|
|||
if (axis3)
|
||||
fprintf(stream_, " variable_3 : %s;\n",
|
||||
tableVariableString(axis3->variable()));
|
||||
if (axis1 && axis1->values())
|
||||
if (axis1 && !axis1->values().empty())
|
||||
writeTableAxis4(axis1, 1);
|
||||
if (axis2 && axis2->values())
|
||||
if (axis2 && !axis2->values().empty())
|
||||
writeTableAxis4(axis2, 2);
|
||||
if (axis3 && axis3->values())
|
||||
if (axis3 && !axis3->values().empty())
|
||||
writeTableAxis4(axis3, 3);
|
||||
fprintf(stream_, " }\n");
|
||||
}
|
||||
|
|
@ -268,7 +268,7 @@ LibertyWriter::writeBusDcls()
|
|||
{
|
||||
BusDclSeq dcls = library_->busDcls();
|
||||
for (BusDcl *dcl : dcls) {
|
||||
fprintf(stream_, " type (\"%s\") {\n", dcl->name());
|
||||
fprintf(stream_, " type (\"%s\") {\n", dcl->name().c_str());
|
||||
fprintf(stream_, " base_type : array;\n");
|
||||
fprintf(stream_, " data_type : bit;\n");
|
||||
fprintf(stream_, " bit_width : %d;\n", abs(dcl->from() - dcl->to() + 1));
|
||||
|
|
@ -333,7 +333,7 @@ LibertyWriter::writeBusPort(const LibertyPort *port)
|
|||
{
|
||||
fprintf(stream_, " bus(\"%s\") {\n", port->name());
|
||||
if (port->busDcl())
|
||||
fprintf(stream_, " bus_type : %s;\n", port->busDcl()->name());
|
||||
fprintf(stream_, " bus_type : %s;\n", port->busDcl()->name().c_str());
|
||||
writePortAttrs(port);
|
||||
|
||||
LibertyPortMemberIterator member_iter(port);
|
||||
|
|
@ -370,10 +370,10 @@ LibertyWriter::writePortAttrs(const LibertyPort *port)
|
|||
three_state->to_string().c_str());
|
||||
}
|
||||
else {
|
||||
FuncExpr three_state(FuncExpr::Op::not_, tristate_enable,
|
||||
nullptr, nullptr);
|
||||
FuncExpr *three_state = tristate_enable->copy()->invert();
|
||||
fprintf(stream_, " three_state : \"%s\";\n",
|
||||
three_state.to_string().c_str());
|
||||
three_state->to_string().c_str());
|
||||
delete three_state;
|
||||
}
|
||||
}
|
||||
if (port->isClock())
|
||||
|
|
@ -392,7 +392,7 @@ LibertyWriter::writePortAttrs(const LibertyPort *port)
|
|||
fprintf(stream_, " max_capacitance : %s;\n",
|
||||
cap_unit_->asString(limit, 3));
|
||||
|
||||
for (TimingArcSet *arc_set : port->libertyCell()->timingArcSets(nullptr,port)) {
|
||||
for (TimingArcSet *arc_set : port->libertyCell()->timingArcSetsTo(port)) {
|
||||
if (!isAutoWidthArc(port, arc_set))
|
||||
writeTimingArcSet(arc_set);
|
||||
}
|
||||
|
|
@ -460,23 +460,23 @@ LibertyWriter::writeTimingModels(const TimingArc *arc,
|
|||
const CheckTableModel *check_model = dynamic_cast<CheckTableModel*>(model);
|
||||
if (gate_model) {
|
||||
const TableModel *delay_model = gate_model->delayModel();
|
||||
const char *template_name = delay_model->tblTemplate()->name();
|
||||
fprintf(stream_, " cell_%s(%s) {\n", rf->name(), template_name);
|
||||
const std::string &template_name = delay_model->tblTemplate()->name();
|
||||
fprintf(stream_, " cell_%s(%s) {\n", rf->name(), template_name.c_str());
|
||||
writeTableModel(delay_model);
|
||||
fprintf(stream_, " }\n");
|
||||
|
||||
const TableModel *slew_model = gate_model->slewModel();
|
||||
if (slew_model) {
|
||||
template_name = slew_model->tblTemplate()->name();
|
||||
fprintf(stream_, " %s_transition(%s) {\n", rf->name(), template_name);
|
||||
const std::string &slew_template_name = slew_model->tblTemplate()->name();
|
||||
fprintf(stream_, " %s_transition(%s) {\n", rf->name(), slew_template_name.c_str());
|
||||
writeTableModel(slew_model);
|
||||
fprintf(stream_, " }\n");
|
||||
}
|
||||
}
|
||||
else if (check_model) {
|
||||
const TableModel *model = check_model->model();
|
||||
const char *template_name = model->tblTemplate()->name();
|
||||
fprintf(stream_, " %s_constraint(%s) {\n", rf->name(), template_name);
|
||||
const std::string &template_name = model->tblTemplate()->name();
|
||||
fprintf(stream_, " %s_constraint(%s) {\n", rf->name(), template_name.c_str());
|
||||
writeTableModel(model);
|
||||
fprintf(stream_, " }\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,16 +49,54 @@ Sequential::Sequential(bool is_register,
|
|||
{
|
||||
}
|
||||
|
||||
Sequential::Sequential(Sequential &&other) noexcept :
|
||||
is_register_(other.is_register_),
|
||||
clock_(other.clock_),
|
||||
data_(other.data_),
|
||||
clear_(other.clear_),
|
||||
preset_(other.preset_),
|
||||
clr_preset_out_(other.clr_preset_out_),
|
||||
clr_preset_out_inv_(other.clr_preset_out_inv_),
|
||||
output_(other.output_),
|
||||
output_inv_(other.output_inv_)
|
||||
{
|
||||
other.clock_ = nullptr;
|
||||
other.data_ = nullptr;
|
||||
other.clear_ = nullptr;
|
||||
other.preset_ = nullptr;
|
||||
}
|
||||
|
||||
Sequential &
|
||||
Sequential::operator=(Sequential &&other) noexcept
|
||||
{
|
||||
if (this != &other) {
|
||||
delete clock_;
|
||||
delete data_;
|
||||
delete clear_;
|
||||
delete preset_;
|
||||
is_register_ = other.is_register_;
|
||||
clock_ = other.clock_;
|
||||
data_ = other.data_;
|
||||
clear_ = other.clear_;
|
||||
preset_ = other.preset_;
|
||||
clr_preset_out_ = other.clr_preset_out_;
|
||||
clr_preset_out_inv_ = other.clr_preset_out_inv_;
|
||||
output_ = other.output_;
|
||||
output_inv_ = other.output_inv_;
|
||||
other.clock_ = nullptr;
|
||||
other.data_ = nullptr;
|
||||
other.clear_ = nullptr;
|
||||
other.preset_ = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Sequential::~Sequential()
|
||||
{
|
||||
if (clock_)
|
||||
clock_->deleteSubexprs();
|
||||
if (data_)
|
||||
data_->deleteSubexprs();
|
||||
if (clear_)
|
||||
clear_->deleteSubexprs();
|
||||
if (preset_)
|
||||
preset_->deleteSubexprs();
|
||||
delete clock_;
|
||||
delete data_;
|
||||
delete clear_;
|
||||
delete preset_;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -51,11 +51,6 @@ TimingArcAttrs::TimingArcAttrs() :
|
|||
timing_type_(TimingType::combinational),
|
||||
timing_sense_(TimingSense::unknown),
|
||||
cond_(nullptr),
|
||||
sdf_cond_(nullptr),
|
||||
sdf_cond_start_(nullptr),
|
||||
sdf_cond_end_(nullptr),
|
||||
mode_name_(nullptr),
|
||||
mode_value_(nullptr),
|
||||
ocv_arc_depth_(0.0),
|
||||
models_{nullptr, nullptr}
|
||||
{
|
||||
|
|
@ -65,11 +60,6 @@ TimingArcAttrs::TimingArcAttrs(TimingSense sense) :
|
|||
timing_type_(TimingType::combinational),
|
||||
timing_sense_(sense),
|
||||
cond_(nullptr),
|
||||
sdf_cond_(nullptr),
|
||||
sdf_cond_start_(nullptr),
|
||||
sdf_cond_end_(nullptr),
|
||||
mode_name_(nullptr),
|
||||
mode_value_(nullptr),
|
||||
ocv_arc_depth_(0.0),
|
||||
models_{nullptr, nullptr}
|
||||
{
|
||||
|
|
@ -77,15 +67,7 @@ TimingArcAttrs::TimingArcAttrs(TimingSense sense) :
|
|||
|
||||
TimingArcAttrs::~TimingArcAttrs()
|
||||
{
|
||||
if (cond_)
|
||||
cond_->deleteSubexprs();
|
||||
if (sdf_cond_start_ != sdf_cond_)
|
||||
stringDelete(sdf_cond_start_);
|
||||
if (sdf_cond_end_ != sdf_cond_)
|
||||
stringDelete(sdf_cond_end_);
|
||||
stringDelete(sdf_cond_);
|
||||
stringDelete(mode_name_);
|
||||
stringDelete(mode_value_);
|
||||
delete cond_;
|
||||
delete models_[RiseFall::riseIndex()];
|
||||
delete models_[RiseFall::fallIndex()];
|
||||
}
|
||||
|
|
@ -109,39 +91,34 @@ TimingArcAttrs::setCond(FuncExpr *cond)
|
|||
}
|
||||
|
||||
void
|
||||
TimingArcAttrs::setSdfCond(const char *cond)
|
||||
TimingArcAttrs::setSdfCond(const std::string &cond)
|
||||
{
|
||||
stringDelete(sdf_cond_);
|
||||
sdf_cond_ = stringCopy(cond);
|
||||
sdf_cond_ = cond;
|
||||
sdf_cond_start_ = sdf_cond_end_ = sdf_cond_;
|
||||
}
|
||||
|
||||
void
|
||||
TimingArcAttrs::setSdfCondStart(const char *cond)
|
||||
TimingArcAttrs::setSdfCondStart(const std::string &cond)
|
||||
{
|
||||
stringDelete(sdf_cond_start_);
|
||||
sdf_cond_start_ = stringCopy(cond);
|
||||
sdf_cond_start_ = cond;
|
||||
}
|
||||
|
||||
void
|
||||
TimingArcAttrs::setSdfCondEnd(const char *cond)
|
||||
TimingArcAttrs::setSdfCondEnd(const std::string &cond)
|
||||
{
|
||||
stringDelete(sdf_cond_end_);
|
||||
sdf_cond_end_ = stringCopy(cond);
|
||||
sdf_cond_end_ = cond;
|
||||
}
|
||||
|
||||
void
|
||||
TimingArcAttrs::setModeName(const char *name)
|
||||
TimingArcAttrs::setModeName(const std::string &name)
|
||||
{
|
||||
stringDelete(mode_name_);
|
||||
mode_name_ = stringCopy(name);
|
||||
mode_name_ = name;
|
||||
}
|
||||
|
||||
void
|
||||
TimingArcAttrs::setModeValue(const char *value)
|
||||
TimingArcAttrs::setModeValue(const std::string &value)
|
||||
{
|
||||
stringDelete(mode_value_);
|
||||
mode_value_ = stringCopy(value);
|
||||
mode_value_ = value;
|
||||
}
|
||||
|
||||
TimingModel *
|
||||
|
|
@ -192,19 +169,20 @@ TimingArc::intrinsicDelay() const
|
|||
TimingArcAttrsPtr TimingArcSet::wire_timing_arc_attrs_ = nullptr;
|
||||
TimingArcSet *TimingArcSet::wire_timing_arc_set_ = nullptr;
|
||||
|
||||
TimingArcSet::TimingArcSet(LibertyCell *cell,
|
||||
TimingArcSet::TimingArcSet(LibertyCell *,
|
||||
LibertyPort *from,
|
||||
LibertyPort *to,
|
||||
LibertyPort *related_out,
|
||||
const TimingRole *role,
|
||||
TimingArcAttrsPtr attrs) :
|
||||
TimingArcAttrsPtr attrs,
|
||||
size_t index) :
|
||||
from_(from),
|
||||
to_(to),
|
||||
related_out_(related_out),
|
||||
role_(role),
|
||||
attrs_(attrs),
|
||||
is_cond_default_(false),
|
||||
index_(cell->addTimingArcSet(this)),
|
||||
index_(index),
|
||||
from_arc1_{nullptr, nullptr},
|
||||
from_arc2_{nullptr, nullptr},
|
||||
to_arc_{nullptr, nullptr}
|
||||
|
|
@ -247,10 +225,10 @@ TimingArcSet::libertyCell() const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
TimingArcIndex
|
||||
size_t
|
||||
TimingArcSet::addTimingArc(TimingArc *arc)
|
||||
{
|
||||
TimingArcIndex arc_index = arcs_.size();
|
||||
size_t arc_index = arcs_.size();
|
||||
// Rise/fall to rise/fall.
|
||||
if (arc_index > RiseFall::index_count * RiseFall::index_count)
|
||||
criticalError(243, "timing arc max index exceeded\n");
|
||||
|
|
@ -303,6 +281,12 @@ TimingArcSet::setRole(const TimingRole *role)
|
|||
role_ = role;
|
||||
}
|
||||
|
||||
void
|
||||
TimingArcSet::setIndex(size_t index)
|
||||
{
|
||||
index_ = index;
|
||||
}
|
||||
|
||||
void
|
||||
TimingArcSet::setIsCondDefault(bool is_default)
|
||||
{
|
||||
|
|
@ -379,9 +363,9 @@ TimingArcSet::equiv(const TimingArcSet *set1,
|
|||
&& LibertyPort::equiv(set1->to(), set2->to())
|
||||
&& set1->role() == set2->role()
|
||||
&& FuncExpr::equiv(set1->cond(), set2->cond())
|
||||
&& stringEqIf(set1->sdfCond(), set2->sdfCond())
|
||||
&& stringEqIf(set1->sdfCondStart(), set2->sdfCondStart())
|
||||
&& stringEqIf(set1->sdfCondEnd(), set2->sdfCondEnd())
|
||||
&& set1->sdfCond() == set2->sdfCond()
|
||||
&& set1->sdfCondStart() == set2->sdfCondStart()
|
||||
&& set1->sdfCondEnd() == set2->sdfCondEnd()
|
||||
&& timingArcsEquiv(set1, set2);
|
||||
}
|
||||
|
||||
|
|
@ -428,36 +412,36 @@ timingArcSetLess(const TimingArcSet *set1,
|
|||
const FuncExpr *cond1 = set1->cond();
|
||||
const FuncExpr *cond2 = set2->cond();
|
||||
if (FuncExpr::equiv(cond1, cond2)) {
|
||||
const char *sdf_cond1 = set1->sdfCond();
|
||||
const char *sdf_cond2 = set2->sdfCond();
|
||||
if (stringEqIf(sdf_cond1, sdf_cond2)) {
|
||||
const char *sdf_cond_start1 = set1->sdfCondStart();
|
||||
const char *sdf_cond_start2 = set2->sdfCondStart();
|
||||
if (stringEqIf(sdf_cond_start1, sdf_cond_start2)) {
|
||||
const char *sdf_cond_end1 = set1->sdfCondEnd();
|
||||
const char *sdf_cond_end2 = set2->sdfCondEnd();
|
||||
if (stringEqIf(sdf_cond_end1, sdf_cond_end2)) {
|
||||
const char *mode_name1 = set1->modeName();
|
||||
const char *mode_name2 = set2->modeName();
|
||||
if (stringEqIf(mode_name1, mode_name2)) {
|
||||
const char *mode_value1 = set1->modeValue();
|
||||
const char *mode_value2 = set2->modeValue();
|
||||
if (stringEqIf(mode_value1, mode_value2))
|
||||
const std::string &sdf_cond1 = set1->sdfCond();
|
||||
const std::string &sdf_cond2 = set2->sdfCond();
|
||||
if (sdf_cond1 == sdf_cond2) {
|
||||
const std::string &sdf_cond_start1 = set1->sdfCondStart();
|
||||
const std::string &sdf_cond_start2 = set2->sdfCondStart();
|
||||
if (sdf_cond_start1 == sdf_cond_start2) {
|
||||
const std::string &sdf_cond_end1 = set1->sdfCondEnd();
|
||||
const std::string &sdf_cond_end2 = set2->sdfCondEnd();
|
||||
if (sdf_cond_end1 == sdf_cond_end2) {
|
||||
const std::string &mode_name1 = set1->modeName();
|
||||
const std::string &mode_name2 = set2->modeName();
|
||||
if (mode_name1 == mode_name2) {
|
||||
const std::string &mode_value1 = set1->modeValue();
|
||||
const std::string &mode_value2 = set2->modeValue();
|
||||
if (mode_value1 == mode_value2)
|
||||
return timingArcsLess(set1, set2);
|
||||
else
|
||||
return stringLessIf(mode_value1, mode_value2);
|
||||
return mode_value1 < mode_value2;
|
||||
}
|
||||
else
|
||||
return stringLessIf(mode_name1, mode_name2);
|
||||
return mode_name1 < mode_name2;
|
||||
}
|
||||
else
|
||||
return stringLessIf(sdf_cond_end1, sdf_cond_end2);
|
||||
return sdf_cond_end1 < sdf_cond_end2;
|
||||
}
|
||||
else
|
||||
return stringLessIf(sdf_cond_start1, sdf_cond_start2);
|
||||
return sdf_cond_start1 < sdf_cond_start2;
|
||||
}
|
||||
else
|
||||
return stringLessIf(sdf_cond1, sdf_cond2);
|
||||
return sdf_cond1 < sdf_cond2;
|
||||
}
|
||||
else
|
||||
return FuncExpr::less(cond1, cond2);
|
||||
|
|
|
|||
|
|
@ -998,9 +998,9 @@ Power::seedRegOutputActivities(const Instance *inst,
|
|||
const SequentialSeq &seqs,
|
||||
BfsFwdIterator &bfs)
|
||||
{
|
||||
for (Sequential *seq : seqs) {
|
||||
seedRegOutputActivities(inst, seq, seq->output(), false);
|
||||
seedRegOutputActivities(inst, seq, seq->outputInv(), true);
|
||||
for (const Sequential &seq : seqs) {
|
||||
seedRegOutputActivities(inst, seq, seq.output(), false);
|
||||
seedRegOutputActivities(inst, seq, seq.outputInv(), true);
|
||||
// Enqueue register output pins with functions that reference
|
||||
// the sequential internal pins (IQ, IQN).
|
||||
InstancePinIterator *pin_iter = network_->pinIterator(inst);
|
||||
|
|
@ -1014,8 +1014,8 @@ Power::seedRegOutputActivities(const Instance *inst,
|
|||
Vertex *vertex = graph_->pinDrvrVertex(pin);
|
||||
if (vertex
|
||||
&& func
|
||||
&& (func->port() == seq->output()
|
||||
|| func->port() == seq->outputInv())) {
|
||||
&& (func->port() == seq.output()
|
||||
|| func->port() == seq.outputInv())) {
|
||||
debugPrint(debug_, "power_reg", 1, "enqueue reg output %s",
|
||||
vertex->to_string(this).c_str());
|
||||
bfs.enqueue(vertex);
|
||||
|
|
@ -1028,27 +1028,27 @@ Power::seedRegOutputActivities(const Instance *inst,
|
|||
|
||||
void
|
||||
Power::seedRegOutputActivities(const Instance *reg,
|
||||
Sequential *seq,
|
||||
const Sequential &seq,
|
||||
LibertyPort *output,
|
||||
bool invert)
|
||||
{
|
||||
const Pin *out_pin = network_->findPin(reg, output);
|
||||
if (!hasUserActivity(out_pin)) {
|
||||
PwrActivity in_activity = evalActivity(seq->data(), reg);
|
||||
PwrActivity in_activity = evalActivity(seq.data(), reg);
|
||||
float in_density = in_activity.density();
|
||||
float in_duty = in_activity.duty();
|
||||
// Default propagates input density/duty thru reg/latch.
|
||||
float out_density = in_density;
|
||||
float out_duty = in_duty;
|
||||
PwrActivity clk_activity = evalActivity(seq->clock(), reg);
|
||||
PwrActivity clk_activity = evalActivity(seq.clock(), reg);
|
||||
float clk_density = clk_activity.density();
|
||||
if (in_density > clk_density / 2) {
|
||||
if (seq->isRegister())
|
||||
if (seq.isRegister())
|
||||
out_density = 2 * in_duty * (1 - in_duty) * clk_density;
|
||||
else if (seq->isLatch()) {
|
||||
PwrActivity clk_activity = evalActivity(seq->clock(), reg);
|
||||
else if (seq.isLatch()) {
|
||||
PwrActivity clk_activity = evalActivity(seq.clock(), reg);
|
||||
float clk_duty = clk_activity.duty();
|
||||
FuncExpr *clk_func = seq->clock();
|
||||
FuncExpr *clk_func = seq.clock();
|
||||
bool clk_invert = clk_func
|
||||
&& clk_func->op() == FuncExpr::Op::not_
|
||||
&& clk_func->left()->op() == FuncExpr::Op::port;
|
||||
|
|
@ -1164,7 +1164,7 @@ Power::findInputInternalPower(const Pin *pin,
|
|||
LibertyCell *scene_cell = cell->sceneCell(scene, min_max);
|
||||
const LibertyPort *scene_port = port->scenePort(scene, min_max);
|
||||
if (scene_cell && scene_port) {
|
||||
const InternalPowerSeq &internal_pwrs = scene_cell->internalPowers(scene_port);
|
||||
const InternalPowerPtrSeq &internal_pwrs = scene_cell->internalPowers(scene_port);
|
||||
if (!internal_pwrs.empty()) {
|
||||
debugPrint(debug_, "power", 2, "internal input %s/%s cap %s",
|
||||
network_->pathName(inst),
|
||||
|
|
@ -1174,8 +1174,8 @@ Power::findInputInternalPower(const Pin *pin,
|
|||
const Pvt *pvt = scene->sdc()->operatingConditions(MinMax::max());
|
||||
Vertex *vertex = graph_->pinLoadVertex(pin);
|
||||
float internal = 0.0;
|
||||
for (InternalPower *pwr : internal_pwrs) {
|
||||
const char *related_pg_pin = pwr->relatedPgPin();
|
||||
for (const InternalPower *pwr : internal_pwrs) {
|
||||
const char *related_pg_pin = pwr->relatedPgPin().c_str();
|
||||
float energy = 0.0;
|
||||
int rf_count = 0;
|
||||
for (const RiseFall *rf : RiseFall::range()) {
|
||||
|
|
@ -1313,13 +1313,13 @@ Power::findOutputInternalPower(const LibertyPort *to_port,
|
|||
FuncExpr *func = to_port->function();
|
||||
|
||||
map<const char*, float, StringLessIf> pg_duty_sum;
|
||||
for (InternalPower *pwr : scene_cell->internalPowers(to_scene_port)) {
|
||||
for (const InternalPower *pwr : scene_cell->internalPowers(to_scene_port)) {
|
||||
const LibertyPort *from_scene_port = pwr->relatedPort();
|
||||
if (from_scene_port) {
|
||||
const Pin *from_pin = findLinkPin(inst, from_scene_port);
|
||||
float from_density = findActivity(from_pin).density();
|
||||
float duty = findInputDuty(inst, func, pwr);
|
||||
const char *related_pg_pin = pwr->relatedPgPin();
|
||||
const char *related_pg_pin = pwr->relatedPgPin().c_str();
|
||||
// Note related_pg_pin may be null.
|
||||
pg_duty_sum[related_pg_pin] += from_density * duty;
|
||||
}
|
||||
|
|
@ -1328,9 +1328,9 @@ Power::findOutputInternalPower(const LibertyPort *to_port,
|
|||
debugPrint(debug_, "power", 2,
|
||||
" when act/ns duty wgt energy power");
|
||||
float internal = 0.0;
|
||||
for (InternalPower *pwr : scene_cell->internalPowers(to_scene_port)) {
|
||||
for (const InternalPower *pwr : scene_cell->internalPowers(to_scene_port)) {
|
||||
FuncExpr *when = pwr->when();
|
||||
const char *related_pg_pin = pwr->relatedPgPin();
|
||||
const char *related_pg_pin = pwr->relatedPgPin().c_str();
|
||||
float duty = findInputDuty(inst, func, pwr);
|
||||
Vertex *from_vertex = nullptr;
|
||||
bool positive_unate = true;
|
||||
|
|
@ -1386,8 +1386,7 @@ Power::findOutputInternalPower(const LibertyPort *to_port,
|
|||
float
|
||||
Power::findInputDuty(const Instance *inst,
|
||||
FuncExpr *func,
|
||||
InternalPower *pwr)
|
||||
|
||||
const InternalPower *pwr)
|
||||
{
|
||||
const LibertyPort *from_scene_port = pwr->relatedPort();
|
||||
if (from_scene_port) {
|
||||
|
|
@ -1494,11 +1493,16 @@ Power::findLeakagePower(const Instance *inst,
|
|||
float uncond_leakage = 0.0;
|
||||
bool found_uncond = false;
|
||||
float cond_duty_sum = 0.0;
|
||||
<<<<<<<
|
||||
for (LeakagePower *leak : *scene_cell->leakagePowers()) {
|
||||
LibertyPort *pg_port = leak->relatedPgPort();
|
||||
if (pg_port == nullptr
|
||||
|| pg_port->pwrGndType() == PwrGndType::primary_power) {
|
||||
FuncExpr *when = leak->when();
|
||||
=======
|
||||
for (const LeakagePower &leak : scene_cell->leakagePowers()) {
|
||||
FuncExpr *when = leak.when();
|
||||
>>>>>>>
|
||||
if (when) {
|
||||
PwrActivity cond_activity = evalActivity(when, inst);
|
||||
float cond_duty = cond_activity.duty();
|
||||
|
|
@ -1506,19 +1510,24 @@ Power::findLeakagePower(const Instance *inst,
|
|||
cell->name(),
|
||||
leak->relatedPgPort()->name(),
|
||||
when->to_string().c_str(),
|
||||
leak->power(),
|
||||
leak.power(),
|
||||
cond_duty);
|
||||
cond_leakage += leak->power() * cond_duty;
|
||||
if (leak->power() > 0.0)
|
||||
cond_leakage += leak.power() * cond_duty;
|
||||
if (leak.power() > 0.0)
|
||||
cond_duty_sum += cond_duty;
|
||||
found_cond = true;
|
||||
}
|
||||
else {
|
||||
debugPrint(debug_, "power", 2, "leakage %s %s -- %.3e",
|
||||
cell->name(),
|
||||
<<<<<<<
|
||||
leak->relatedPgPort()->name(),
|
||||
leak->power());
|
||||
uncond_leakage += leak->power();
|
||||
=======
|
||||
leak.power());
|
||||
uncond_leakage += leak.power();
|
||||
>>>>>>>
|
||||
found_uncond = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ protected:
|
|||
const MinMax *min_max);
|
||||
void seedActivities(BfsFwdIterator &bfs);
|
||||
void seedRegOutputActivities(const Instance *reg,
|
||||
Sequential *seq,
|
||||
const Sequential &seq,
|
||||
LibertyPort *output,
|
||||
bool invert);
|
||||
void seedRegOutputActivities(const Instance *inst,
|
||||
|
|
@ -233,7 +233,7 @@ protected:
|
|||
LibertyPort *findExprOutPort(FuncExpr *expr);
|
||||
float findInputDuty(const Instance *inst,
|
||||
FuncExpr *func,
|
||||
InternalPower *pwr);
|
||||
const InternalPower *pwr);
|
||||
float evalDiffDuty(FuncExpr *expr,
|
||||
LibertyPort *from_port,
|
||||
const Instance *inst);
|
||||
|
|
|
|||
|
|
@ -3870,7 +3870,7 @@ Sdc::isExceptionEndpoint(const Pin *pin) const
|
|||
// Look for timing checks to the pin witihout using the graph because
|
||||
// it may not exist.
|
||||
LibertyCell *cell = port->libertyCell();
|
||||
for (TimingArcSet *arc_set : cell->timingArcSets(nullptr, port)) {
|
||||
for (TimingArcSet *arc_set : cell->timingArcSetsTo(port)) {
|
||||
if (arc_set->role()->isTimingCheck()) {
|
||||
has_checks = true;
|
||||
break;
|
||||
|
|
@ -4046,7 +4046,7 @@ Sdc::hasLibertyCheckTo(const Pin *pin)
|
|||
if (cell) {
|
||||
LibertyPort *port = network_->libertyPort(pin);
|
||||
if (port) {
|
||||
for (TimingArcSet *arc_set : cell->timingArcSets(nullptr, port)) {
|
||||
for (TimingArcSet *arc_set : cell->timingArcSetsTo(port)) {
|
||||
if (arc_set->role()->isTimingCheckBetween())
|
||||
return true;
|
||||
}
|
||||
|
|
@ -5645,7 +5645,7 @@ Sdc::wireloadSelection(const MinMax *min_max)
|
|||
// Look for a default.
|
||||
LibertyLibrary *lib = network_->defaultLibertyLibrary();
|
||||
if (lib) {
|
||||
WireloadSelection *default_sel = lib->defaultWireloadSelection();
|
||||
const WireloadSelection *default_sel = lib->defaultWireloadSelection();
|
||||
if (default_sel) {
|
||||
sel = default_sel;
|
||||
setWireloadSelection(default_sel, MinMaxAll::all());
|
||||
|
|
@ -5656,7 +5656,7 @@ Sdc::wireloadSelection(const MinMax *min_max)
|
|||
}
|
||||
|
||||
void
|
||||
Sdc::setWireloadSelection(WireloadSelection *selection,
|
||||
Sdc::setWireloadSelection(const WireloadSelection *selection,
|
||||
const MinMaxAll *min_max)
|
||||
{
|
||||
for (auto mm_index : min_max->rangeIndex())
|
||||
|
|
|
|||
|
|
@ -519,12 +519,12 @@ ReportAnnotated::reportArcs(Vertex *vertex,
|
|||
}
|
||||
else
|
||||
role_name = "delay";
|
||||
const char *cond = edge->timingArcSet()->sdfCond();
|
||||
const std::string &cond = edge->timingArcSet()->sdfCond();
|
||||
report_->reportLine(" %-18s %s -> %s %s",
|
||||
role_name,
|
||||
network_->pathName(from_pin),
|
||||
network_->pathName(to_pin),
|
||||
cond ? cond : "");
|
||||
cond.c_str());
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -371,16 +371,16 @@ SdfReader::iopath(SdfPortSpec *from_edge,
|
|||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
TimingArcSet *arc_set = edge->timingArcSet();
|
||||
const char *lib_cond = arc_set->sdfCond();
|
||||
const std::string &lib_cond = arc_set->sdfCond();
|
||||
const TimingRole *edge_role = arc_set->role();
|
||||
bool cond_use_flag = cond_use_ && cond && lib_cond == nullptr
|
||||
bool cond_use_flag = cond_use_ && cond && lib_cond.empty()
|
||||
&& !(!is_incremental_only_ && in_incremental_);
|
||||
if (edge->from(graph_)->pin() == from_pin
|
||||
&& edge_role->sdfRole() == TimingRole::sdfIopath()
|
||||
&& (cond_use_flag
|
||||
|| (!condelse && condMatch(cond, lib_cond))
|
||||
// condelse matches the default (unconditional) arc.
|
||||
|| (condelse && lib_cond == nullptr))) {
|
||||
|| (condelse && lib_cond.empty()))) {
|
||||
matched = true;
|
||||
for (TimingArc *arc : arc_set->arcs()) {
|
||||
if ((from_edge->transition() == Transition::riseFall())
|
||||
|
|
@ -526,8 +526,8 @@ SdfReader::annotateCheckEdges(Pin *data_pin,
|
|||
if (edge->from(graph_)->pin() == clk_pin) {
|
||||
TimingArcSet *arc_set = edge->timingArcSet();
|
||||
const TimingRole *edge_role = arc_set->role();
|
||||
const char *lib_cond_start = arc_set->sdfCondStart();
|
||||
const char *lib_cond_end = arc_set->sdfCondEnd();
|
||||
const std::string &lib_cond_start = arc_set->sdfCondStart();
|
||||
const std::string &lib_cond_end = arc_set->sdfCondEnd();
|
||||
bool cond_matches = condMatch(cond_start, lib_cond_start)
|
||||
&& condMatch(cond_end, lib_cond_end);
|
||||
if (((!match_generic && edge_role->sdfRole() == sdf_role)
|
||||
|
|
@ -800,15 +800,15 @@ SdfReader::setEdgeArcDelaysCondUse(Edge *edge,
|
|||
|
||||
bool
|
||||
SdfReader::condMatch(const string *sdf_cond,
|
||||
const char *lib_cond)
|
||||
const std::string &lib_cond)
|
||||
{
|
||||
// If the sdf is not conditional it matches any library condition.
|
||||
if (sdf_cond == nullptr)
|
||||
return true;
|
||||
else if (sdf_cond && lib_cond) {
|
||||
else if (sdf_cond && !lib_cond.empty()) {
|
||||
// Match sdf_cond and lib_cond ignoring blanks.
|
||||
const char *c1 = sdf_cond->c_str();
|
||||
const char *c2 = lib_cond;
|
||||
const char *c2 = lib_cond.c_str();
|
||||
char ch1, ch2;
|
||||
do {
|
||||
ch1 = *c1++;
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ private:
|
|||
Edge *findWireEdge(Pin *from_pin,
|
||||
Pin *to_pin);
|
||||
bool condMatch(const std::string *sdf_cond,
|
||||
const char *lib_cond);
|
||||
const std::string &lib_cond);
|
||||
void timingCheck1(const TimingRole *role,
|
||||
Port *data_port,
|
||||
SdfPortSpec *data_edge,
|
||||
|
|
|
|||
|
|
@ -387,9 +387,9 @@ SdfWriter::writeIopaths(const Instance *inst,
|
|||
writeIopathHeader();
|
||||
iopath_header = true;
|
||||
}
|
||||
const char *sdf_cond = edge->timingArcSet()->sdfCond();
|
||||
if (sdf_cond) {
|
||||
gzprintf(stream_, " (COND %s\n", sdf_cond);
|
||||
const std::string &sdf_cond = edge->timingArcSet()->sdfCond();
|
||||
if (!sdf_cond.empty()) {
|
||||
gzprintf(stream_, " (COND %s\n", sdf_cond.c_str());
|
||||
gzprintf(stream_, " ");
|
||||
}
|
||||
string from_pin_name = sdfPortName(from_pin);
|
||||
|
|
@ -398,7 +398,7 @@ SdfWriter::writeIopaths(const Instance *inst,
|
|||
from_pin_name.c_str(),
|
||||
to_pin_name.c_str());
|
||||
writeArcDelays(edge);
|
||||
if (sdf_cond)
|
||||
if (!sdf_cond.empty())
|
||||
gzprintf(stream_, ")");
|
||||
gzprintf(stream_, ")\n");
|
||||
}
|
||||
|
|
@ -653,13 +653,13 @@ SdfWriter::writeCheck(Edge *edge,
|
|||
TimingArcSet *arc_set = edge->timingArcSet();
|
||||
Pin *from_pin = edge->from(graph_)->pin();
|
||||
Pin *to_pin = edge->to(graph_)->pin();
|
||||
const char *sdf_cond_start = arc_set->sdfCondStart();
|
||||
const char *sdf_cond_end = arc_set->sdfCondEnd();
|
||||
const std::string &sdf_cond_start = arc_set->sdfCondStart();
|
||||
const std::string &sdf_cond_end = arc_set->sdfCondEnd();
|
||||
|
||||
gzprintf(stream_, " (%s ", sdf_check);
|
||||
|
||||
if (sdf_cond_start)
|
||||
gzprintf(stream_, "(COND %s ", sdf_cond_start);
|
||||
if (!sdf_cond_start.empty())
|
||||
gzprintf(stream_, "(COND %s ", sdf_cond_start.c_str());
|
||||
|
||||
string to_pin_name = sdfPortName(to_pin);
|
||||
if (use_data_edge) {
|
||||
|
|
@ -670,13 +670,13 @@ SdfWriter::writeCheck(Edge *edge,
|
|||
else
|
||||
gzprintf(stream_, "%s", to_pin_name.c_str());
|
||||
|
||||
if (sdf_cond_start)
|
||||
if (!sdf_cond_start.empty())
|
||||
gzprintf(stream_, ")");
|
||||
|
||||
gzprintf(stream_, " ");
|
||||
|
||||
if (sdf_cond_end)
|
||||
gzprintf(stream_, "(COND %s ", sdf_cond_end);
|
||||
if (!sdf_cond_end.empty())
|
||||
gzprintf(stream_, "(COND %s ", sdf_cond_end.c_str());
|
||||
|
||||
string from_pin_name = sdfPortName(from_pin);
|
||||
if (use_clk_edge)
|
||||
|
|
@ -686,7 +686,7 @@ SdfWriter::writeCheck(Edge *edge,
|
|||
else
|
||||
gzprintf(stream_, "%s", from_pin_name.c_str());
|
||||
|
||||
if (sdf_cond_end)
|
||||
if (!sdf_cond_end.empty())
|
||||
gzprintf(stream_, ")");
|
||||
|
||||
gzprintf(stream_, " ");
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ private:
|
|||
bool latches);
|
||||
virtual void visitReg(Instance *inst) = 0;
|
||||
virtual void visitSequential(Instance *inst,
|
||||
Sequential *seq) = 0;
|
||||
const Sequential *seq) = 0;
|
||||
void visitFanoutRegs(Vertex *from_vertex,
|
||||
TimingSense from_sense,
|
||||
const RiseFallBoth *clk_rf,
|
||||
|
|
@ -241,17 +241,17 @@ FindRegVisitor::findSequential(const Pin *clk_pin,
|
|||
{
|
||||
has_seqs = false;
|
||||
matches = false;
|
||||
for (Sequential *seq : cell->sequentials()) {
|
||||
for (const Sequential &seq : cell->sequentials()) {
|
||||
has_seqs = true;
|
||||
if ((seq->isRegister() && edge_triggered)
|
||||
|| (seq->isLatch() && latches)) {
|
||||
if ((seq.isRegister() && edge_triggered)
|
||||
|| (seq.isLatch() && latches)) {
|
||||
if (clk_rf == RiseFallBoth::riseFall()) {
|
||||
visitSequential(inst, seq);
|
||||
visitSequential(inst, &seq);
|
||||
matches = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
FuncExpr *clk_func = seq->clock();
|
||||
FuncExpr *clk_func = seq.clock();
|
||||
LibertyPort *port = network_->libertyPort(clk_pin);
|
||||
TimingSense port_sense = clk_func->portTimingSense(port);
|
||||
TimingSense path_sense = pathSenseThru(clk_sense, port_sense);
|
||||
|
|
@ -259,7 +259,7 @@ FindRegVisitor::findSequential(const Pin *clk_pin,
|
|||
&& clk_rf == RiseFallBoth::rise())
|
||||
|| (path_sense == TimingSense::negative_unate
|
||||
&& clk_rf == RiseFallBoth::fall())) {
|
||||
visitSequential(inst, seq);
|
||||
visitSequential(inst, &seq);
|
||||
matches = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -324,7 +324,7 @@ public:
|
|||
private:
|
||||
virtual void visitReg(Instance *inst);
|
||||
virtual void visitSequential(Instance *inst,
|
||||
Sequential *seq);
|
||||
const Sequential *seq);
|
||||
|
||||
InstanceSet regs_;
|
||||
};
|
||||
|
|
@ -348,7 +348,7 @@ FindRegInstances::findRegs(ClockSet *clks,
|
|||
|
||||
void
|
||||
FindRegInstances::visitSequential(Instance *,
|
||||
Sequential *)
|
||||
const Sequential *)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -385,14 +385,14 @@ public:
|
|||
protected:
|
||||
virtual void visitReg(Instance *inst);
|
||||
virtual void visitSequential(Instance *inst,
|
||||
Sequential *seq);
|
||||
const Sequential *seq);
|
||||
virtual bool matchPin(Pin *pin);
|
||||
void visitExpr(FuncExpr *expr,
|
||||
Instance *inst,
|
||||
Sequential *seq);
|
||||
const Sequential *seq);
|
||||
// Sequential expressions to find instance pins.
|
||||
virtual FuncExpr *seqExpr1(Sequential *seq) = 0;
|
||||
virtual FuncExpr *seqExpr2(Sequential *seq) = 0;
|
||||
virtual FuncExpr *seqExpr1(const Sequential *seq) = 0;
|
||||
virtual FuncExpr *seqExpr2(const Sequential *seq) = 0;
|
||||
|
||||
PinSet pins_;
|
||||
};
|
||||
|
|
@ -416,7 +416,7 @@ FindRegPins::findPins(ClockSet *clks,
|
|||
|
||||
void
|
||||
FindRegPins::visitSequential(Instance *inst,
|
||||
Sequential *seq)
|
||||
const Sequential *seq)
|
||||
{
|
||||
visitExpr(seqExpr1(seq), inst, seq);
|
||||
visitExpr(seqExpr2(seq), inst, seq);
|
||||
|
|
@ -425,7 +425,7 @@ FindRegPins::visitSequential(Instance *inst,
|
|||
void
|
||||
FindRegPins::visitExpr(FuncExpr *expr,
|
||||
Instance *inst,
|
||||
Sequential *)
|
||||
const Sequential *)
|
||||
{
|
||||
if (expr) {
|
||||
LibertyPortSet ports = expr->ports();
|
||||
|
|
@ -462,8 +462,8 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool matchPin(Pin *pin);
|
||||
virtual FuncExpr *seqExpr1(Sequential *seq);
|
||||
virtual FuncExpr *seqExpr2(Sequential *seq);
|
||||
virtual FuncExpr *seqExpr1(const Sequential *seq);
|
||||
virtual FuncExpr *seqExpr2(const Sequential *seq);
|
||||
};
|
||||
|
||||
FindRegDataPins::FindRegDataPins(const StaState *sta) :
|
||||
|
|
@ -472,13 +472,13 @@ FindRegDataPins::FindRegDataPins(const StaState *sta) :
|
|||
}
|
||||
|
||||
FuncExpr *
|
||||
FindRegDataPins::seqExpr1(Sequential *seq)
|
||||
FindRegDataPins::seqExpr1(const Sequential *seq)
|
||||
{
|
||||
return seq->data();
|
||||
}
|
||||
|
||||
FuncExpr *
|
||||
FindRegDataPins::seqExpr2(Sequential *)
|
||||
FindRegDataPins::seqExpr2(const Sequential *)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -529,8 +529,8 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool matchPin(Pin *pin);
|
||||
virtual FuncExpr *seqExpr1(Sequential *seq);
|
||||
virtual FuncExpr *seqExpr2(Sequential *seq);
|
||||
virtual FuncExpr *seqExpr1(const Sequential *seq);
|
||||
virtual FuncExpr *seqExpr2(const Sequential *seq);
|
||||
};
|
||||
|
||||
FindRegClkPins::FindRegClkPins(const StaState *sta) :
|
||||
|
|
@ -544,7 +544,7 @@ FindRegClkPins::matchPin(Pin *pin)
|
|||
// Liberty port clock attribute is not present in latches (for nlc18 anyway).
|
||||
LibertyPort *port = network_->libertyPort(pin);
|
||||
LibertyCell *cell = port->libertyCell();
|
||||
for (TimingArcSet *arc_set : cell->timingArcSets(port, nullptr)) {
|
||||
for (TimingArcSet *arc_set : cell->timingArcSetsFrom(port)) {
|
||||
const TimingRole *role = arc_set->role();
|
||||
if (role == TimingRole::regClkToQ()
|
||||
|| role == TimingRole::latchEnToQ())
|
||||
|
|
@ -555,13 +555,13 @@ FindRegClkPins::matchPin(Pin *pin)
|
|||
|
||||
|
||||
FuncExpr *
|
||||
FindRegClkPins::seqExpr1(Sequential *seq)
|
||||
FindRegClkPins::seqExpr1(const Sequential *seq)
|
||||
{
|
||||
return seq->clock();
|
||||
}
|
||||
|
||||
FuncExpr *
|
||||
FindRegClkPins::seqExpr2(Sequential *)
|
||||
FindRegClkPins::seqExpr2(const Sequential *)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -587,8 +587,8 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool matchPin(Pin *pin);
|
||||
virtual FuncExpr *seqExpr1(Sequential *seq) { return seq->clear(); }
|
||||
virtual FuncExpr *seqExpr2(Sequential *seq) { return seq->preset(); }
|
||||
virtual FuncExpr *seqExpr1(const Sequential *seq) { return seq->clear(); }
|
||||
virtual FuncExpr *seqExpr2(const Sequential *seq) { return seq->preset(); }
|
||||
};
|
||||
|
||||
FindRegAsyncPins::FindRegAsyncPins(const StaState *sta) :
|
||||
|
|
@ -601,7 +601,7 @@ FindRegAsyncPins::matchPin(Pin *pin)
|
|||
{
|
||||
LibertyPort *port = network_->libertyPort(pin);
|
||||
LibertyCell *cell = port->libertyCell();
|
||||
for (TimingArcSet *arc_set : cell->timingArcSets(port, nullptr)) {
|
||||
for (TimingArcSet *arc_set : cell->timingArcSetsFrom(port)) {
|
||||
const TimingRole *role = arc_set->role();
|
||||
if (role == TimingRole::regSetClr())
|
||||
return true;
|
||||
|
|
@ -631,12 +631,12 @@ public:
|
|||
private:
|
||||
virtual bool matchPin(Pin *pin);
|
||||
virtual void visitSequential(Instance *inst,
|
||||
Sequential *seq);
|
||||
const Sequential *seq);
|
||||
void visitOutput(LibertyPort *port,
|
||||
Instance *inst);
|
||||
// Unused.
|
||||
virtual FuncExpr *seqExpr1(Sequential *seq);
|
||||
virtual FuncExpr *seqExpr2(Sequential *seq);
|
||||
virtual FuncExpr *seqExpr1(const Sequential *seq);
|
||||
virtual FuncExpr *seqExpr2(const Sequential *seq);
|
||||
};
|
||||
|
||||
FindRegOutputPins::FindRegOutputPins(const StaState *sta) :
|
||||
|
|
@ -649,7 +649,7 @@ FindRegOutputPins::matchPin(Pin *pin)
|
|||
{
|
||||
LibertyPort *port = network_->libertyPort(pin);
|
||||
LibertyCell *cell = port->libertyCell();
|
||||
for (TimingArcSet *arc_set : cell->timingArcSets(nullptr, port)) {
|
||||
for (TimingArcSet *arc_set : cell->timingArcSetsTo( port)) {
|
||||
const TimingRole *role = arc_set->role();
|
||||
if (role == TimingRole::regClkToQ()
|
||||
|| role == TimingRole::latchEnToQ()
|
||||
|
|
@ -661,7 +661,7 @@ FindRegOutputPins::matchPin(Pin *pin)
|
|||
|
||||
void
|
||||
FindRegOutputPins::visitSequential(Instance *inst,
|
||||
Sequential *seq)
|
||||
const Sequential *seq)
|
||||
{
|
||||
visitOutput(seq->output(), inst);
|
||||
visitOutput(seq->outputInv(), inst);
|
||||
|
|
@ -690,13 +690,13 @@ FindRegOutputPins::visitOutput(LibertyPort *port,
|
|||
}
|
||||
|
||||
FuncExpr *
|
||||
FindRegOutputPins::seqExpr1(Sequential *)
|
||||
FindRegOutputPins::seqExpr1(const Sequential *)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FuncExpr *
|
||||
FindRegOutputPins::seqExpr2(Sequential *)
|
||||
FindRegOutputPins::seqExpr2(const Sequential *)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,8 +196,7 @@ MakeTimingModel::makePorts()
|
|||
if (network_->isBus(port)) {
|
||||
int from_index = network_->fromIndex(port);
|
||||
int to_index = network_->toIndex(port);
|
||||
BusDcl *bus_dcl = new BusDcl(port_name, from_index, to_index);
|
||||
library_->addBusDcl(bus_dcl);
|
||||
BusDcl *bus_dcl = library_->makeBusDcl(port_name, from_index, to_index);
|
||||
LibertyPort *lib_port = lib_builder_->makeBusPort(cell_, port_name,
|
||||
from_index, to_index,
|
||||
bus_dcl);
|
||||
|
|
@ -590,7 +589,7 @@ MakeTimingModel::makeClkTreePaths(LibertyPort *lib_port,
|
|||
const TimingRole *role = (min_max == MinMax::min())
|
||||
? TimingRole::clockTreePathMin()
|
||||
: TimingRole::clockTreePathMax();
|
||||
lib_builder_->makeClockTreePathArcs(cell_, lib_port, role, min_max, attrs);
|
||||
lib_builder_->makeClockTreePathArcs(cell_, lib_port, role, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -607,7 +606,7 @@ MakeTimingModel::makeScalarCheckModel(float value,
|
|||
ScaleFactorType scale_factor_type,
|
||||
const RiseFall *rf)
|
||||
{
|
||||
TablePtr table = make_shared<Table0>(value);
|
||||
TablePtr table = make_shared<Table>(value);
|
||||
TableTemplate *tbl_template =
|
||||
library_->findTableTemplate("scalar", TableTemplateType::delay);
|
||||
TableModel *table_model = new TableModel(table, tbl_template,
|
||||
|
|
@ -621,8 +620,8 @@ MakeTimingModel::makeGateModelScalar(Delay delay,
|
|||
Slew slew,
|
||||
const RiseFall *rf)
|
||||
{
|
||||
TablePtr delay_table = make_shared<Table0>(delayAsFloat(delay));
|
||||
TablePtr slew_table = make_shared<Table0>(delayAsFloat(slew));
|
||||
TablePtr delay_table = make_shared<Table>(delayAsFloat(delay));
|
||||
TablePtr slew_table = make_shared<Table>(delayAsFloat(slew));
|
||||
TableTemplate *tbl_template =
|
||||
library_->findTableTemplate("scalar", TableTemplateType::delay);
|
||||
TableModel *delay_model = new TableModel(delay_table, tbl_template,
|
||||
|
|
@ -639,7 +638,7 @@ TimingModel *
|
|||
MakeTimingModel::makeGateModelScalar(Delay delay,
|
||||
const RiseFall *rf)
|
||||
{
|
||||
TablePtr delay_table = make_shared<Table0>(delayAsFloat(delay));
|
||||
TablePtr delay_table = make_shared<Table>(delayAsFloat(delay));
|
||||
TableTemplate *tbl_template =
|
||||
library_->findTableTemplate("scalar", TableTemplateType::delay);
|
||||
TableModel *delay_model = new TableModel(delay_table, tbl_template,
|
||||
|
|
@ -664,7 +663,7 @@ MakeTimingModel::makeGateModelTable(const Pin *output_pin,
|
|||
const LibertyPort *drvr_port = network_->libertyPort(drvr_pin);
|
||||
if (drvr_port) {
|
||||
const LibertyCell *drvr_cell = drvr_port->libertyCell();
|
||||
for (TimingArcSet *arc_set : drvr_cell->timingArcSets(nullptr, drvr_port)) {
|
||||
for (TimingArcSet *arc_set : drvr_cell->timingArcSetsTo(drvr_port)) {
|
||||
for (TimingArc *drvr_arc : arc_set->arcs()) {
|
||||
// Use the first timing arc to simplify life.
|
||||
if (drvr_arc->toEdge()->asRiseFall() == rf) {
|
||||
|
|
@ -692,11 +691,11 @@ MakeTimingModel::makeGateModelTable(const Pin *output_pin,
|
|||
const TableTemplate *drvr_template = drvr_table->tblTemplate();
|
||||
const TableAxis *drvr_load_axis = loadCapacitanceAxis(drvr_table);
|
||||
if (drvr_load_axis) {
|
||||
const FloatSeq *drvr_axis_values = drvr_load_axis->values();
|
||||
const FloatSeq &drvr_axis_values = drvr_load_axis->values();
|
||||
FloatSeq *load_values = new FloatSeq;
|
||||
FloatSeq *slew_values = new FloatSeq;
|
||||
for (size_t i = 0; i < drvr_axis_values->size(); i++) {
|
||||
float load_cap = (*drvr_axis_values)[i];
|
||||
for (size_t i = 0; i < drvr_axis_values.size(); i++) {
|
||||
float load_cap = drvr_axis_values[i];
|
||||
// get slew from driver input pin
|
||||
ArcDelay gate_delay;
|
||||
Slew gate_slew;
|
||||
|
|
@ -708,13 +707,13 @@ MakeTimingModel::makeGateModelTable(const Pin *output_pin,
|
|||
slew_values->push_back(delayAsFloat(gate_slew));
|
||||
}
|
||||
|
||||
FloatSeq *axis_values = new FloatSeq(*drvr_axis_values);
|
||||
FloatSeq axis_values = drvr_axis_values;
|
||||
TableAxisPtr load_axis =
|
||||
std::make_shared<TableAxis>(TableAxisVariable::total_output_net_capacitance,
|
||||
axis_values);
|
||||
std::move(axis_values));
|
||||
|
||||
TablePtr delay_table = make_shared<Table1>(load_values, load_axis);
|
||||
TablePtr slew_table = make_shared<Table1>(slew_values, load_axis);
|
||||
TablePtr delay_table = make_shared<Table>(load_values, load_axis);
|
||||
TablePtr slew_table = make_shared<Table>(slew_values, load_axis);
|
||||
|
||||
TableTemplate *model_template = ensureTableTemplate(drvr_template,
|
||||
load_axis);
|
||||
|
|
@ -748,9 +747,9 @@ MakeTimingModel::ensureTableTemplate(const TableTemplate *drvr_template,
|
|||
string template_name = "template_";
|
||||
template_name += std::to_string(tbl_template_index_++);
|
||||
|
||||
model_template = new TableTemplate(template_name.c_str());
|
||||
model_template = library_->makeTableTemplate(template_name,
|
||||
TableTemplateType::delay);
|
||||
model_template->setAxis1(load_axis);
|
||||
library_->addTableTemplate(model_template, TableTemplateType::delay);
|
||||
template_map_[drvr_template] = model_template;
|
||||
}
|
||||
return model_template;
|
||||
|
|
|
|||
|
|
@ -894,13 +894,13 @@ Sim::isDisabledMode(Edge *edge,
|
|||
is_disabled = false;
|
||||
disable_cond = 0;
|
||||
TimingArcSet *arc_set = edge->timingArcSet();
|
||||
const char *mode_name = arc_set->modeName();
|
||||
const char *mode_value = arc_set->modeValue();
|
||||
if (mode_name && mode_value) {
|
||||
const std::string &mode_name = arc_set->modeName();
|
||||
const std::string &mode_value = arc_set->modeValue();
|
||||
if (!mode_name.empty() && !mode_value.empty()) {
|
||||
LibertyCell *cell = network_->libertyCell(inst);
|
||||
ModeDef *mode_def = cell->findModeDef(mode_name);
|
||||
const ModeDef *mode_def = cell->findModeDef(mode_name.c_str());
|
||||
if (mode_def) {
|
||||
ModeValueDef *value_def = mode_def->findValueDef(mode_value);
|
||||
const ModeValueDef *value_def = mode_def->findValueDef(mode_value.c_str());
|
||||
if (value_def) {
|
||||
FuncExpr *cond = value_def->cond();
|
||||
if (cond) {
|
||||
|
|
@ -908,16 +908,14 @@ Sim::isDisabledMode(Edge *edge,
|
|||
if (cond_value == LogicValue::zero) {
|
||||
// For a mode value to be disabled by having a value of
|
||||
// logic zero one mode value must logic one.
|
||||
for (const auto [name, value_def] : *mode_def->values()) {
|
||||
if (value_def) {
|
||||
FuncExpr *cond1 = value_def->cond();
|
||||
if (cond1) {
|
||||
LogicValue cond_value1 = evalExpr(cond1, inst);
|
||||
if (cond_value1 == LogicValue::one) {
|
||||
disable_cond = cond;
|
||||
is_disabled = true;
|
||||
break;
|
||||
}
|
||||
for (const auto &[name, value_def] : *mode_def->values()) {
|
||||
FuncExpr *cond1 = value_def.cond();
|
||||
if (cond1) {
|
||||
LogicValue cond_value1 = evalExpr(cond1, inst);
|
||||
if (cond_value1 == LogicValue::one) {
|
||||
disable_cond = cond;
|
||||
is_disabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,6 +254,7 @@ deleteAllMemory()
|
|||
deleteDelayCalcs();
|
||||
PortDirection::destroy();
|
||||
deleteLiberty();
|
||||
deleteTmpStrings();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -760,7 +760,7 @@ WriteSpice::writeWaveformVoltSource(const Pin *pin,
|
|||
volt_index_++,
|
||||
network_->pathName(pin));
|
||||
streamPrint(spice_stream_, "+%.3e %.3e\n", 0.0, volt0);
|
||||
Table1 waveform = drvr_waveform->waveform(slew);
|
||||
Table waveform = drvr_waveform->waveform(slew);
|
||||
const TableAxis *time_axis = waveform.axis1();
|
||||
for (size_t time_index = 0; time_index < time_axis->size(); time_index++) {
|
||||
float time = delay + time_axis->axisValue(time_index);
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ readXyceCsv(const char *csv_filename,
|
|||
}
|
||||
file.close();
|
||||
TableAxisPtr time_axis = make_shared<TableAxis>(TableAxisVariable::time,
|
||||
new FloatSeq(values[0]));
|
||||
std::move(values[0]));
|
||||
for (size_t var = 1; var < values.size(); var++)
|
||||
waveforms.emplace_back(new FloatSeq(values[var]), time_axis);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
namespace sta {
|
||||
|
||||
using StdStringSeq = std::vector<std::string>;
|
||||
using WaveformSeq = std::vector<Table1>;
|
||||
using WaveformSeq = std::vector<Table>;
|
||||
|
||||
void
|
||||
readXyceCsv(const char *csv_filename,
|
||||
|
|
|
|||
|
|
@ -837,19 +837,21 @@ using namespace sta;
|
|||
$1 = ints;
|
||||
}
|
||||
|
||||
%typemap(out) Table1 {
|
||||
Table1 &table = $1;
|
||||
%typemap(out) Table {
|
||||
Table &table = $1;
|
||||
if (table.axis1()) {
|
||||
Tcl_Obj *list3 = Tcl_NewListObj(0, nullptr);
|
||||
Tcl_Obj *list1 = Tcl_NewListObj(0, nullptr);
|
||||
for (float f : *table.axis1()->values()) {
|
||||
for (float f : table.axis1()->values()) {
|
||||
Tcl_Obj *obj = Tcl_NewDoubleObj(f);
|
||||
Tcl_ListObjAppendElement(interp, list1, obj);
|
||||
}
|
||||
Tcl_Obj *list2 = Tcl_NewListObj(0, nullptr);
|
||||
for (float f : *table.values()) {
|
||||
Tcl_Obj *obj = Tcl_NewDoubleObj(f);
|
||||
Tcl_ListObjAppendElement(interp, list2, obj);
|
||||
if (table.values()) {
|
||||
for (float f : *table.values()) {
|
||||
Tcl_Obj *obj = Tcl_NewDoubleObj(f);
|
||||
Tcl_ListObjAppendElement(interp, list2, obj);
|
||||
}
|
||||
}
|
||||
Tcl_ListObjAppendElement(interp, list3, list1);
|
||||
Tcl_ListObjAppendElement(interp, list3, list2);
|
||||
|
|
@ -857,19 +859,23 @@ using namespace sta;
|
|||
}
|
||||
}
|
||||
|
||||
%typemap(out) const Table1* {
|
||||
const Table1 *table = $1;
|
||||
%typemap(out) const Table* {
|
||||
const Table *table = $1;
|
||||
Tcl_Obj *list3 = Tcl_NewListObj(0, nullptr);
|
||||
if (table) {
|
||||
Tcl_Obj *list1 = Tcl_NewListObj(0, nullptr);
|
||||
for (float f : *table->axis1()->values()) {
|
||||
Tcl_Obj *obj = Tcl_NewDoubleObj(f);
|
||||
Tcl_ListObjAppendElement(interp, list1, obj);
|
||||
if (table->axis1()) {
|
||||
for (float f : table->axis1()->values()) {
|
||||
Tcl_Obj *obj = Tcl_NewDoubleObj(f);
|
||||
Tcl_ListObjAppendElement(interp, list1, obj);
|
||||
}
|
||||
}
|
||||
Tcl_Obj *list2 = Tcl_NewListObj(0, nullptr);
|
||||
for (float f : *table->values()) {
|
||||
Tcl_Obj *obj = Tcl_NewDoubleObj(f);
|
||||
Tcl_ListObjAppendElement(interp, list2, obj);
|
||||
if (table->values()) {
|
||||
for (float f : *table->values()) {
|
||||
Tcl_Obj *obj = Tcl_NewDoubleObj(f);
|
||||
Tcl_ListObjAppendElement(interp, list2, obj);
|
||||
}
|
||||
}
|
||||
Tcl_ListObjAppendElement(interp, list3, list1);
|
||||
Tcl_ListObjAppendElement(interp, list3, list2);
|
||||
|
|
|
|||
|
|
@ -186,6 +186,17 @@ thread_local static std::array<char*, tmp_string_count> tmp_strings;
|
|||
thread_local static std::array<size_t, tmp_string_count> tmp_string_lengths;
|
||||
thread_local static int tmp_string_next = 0;
|
||||
|
||||
void
|
||||
deleteTmpStrings()
|
||||
{
|
||||
for (size_t i = 0; i < tmp_string_count; i++) {
|
||||
stringDelete(tmp_strings[i]);
|
||||
tmp_string_lengths[i] = 0;
|
||||
tmp_strings[i] = nullptr;
|
||||
}
|
||||
tmp_string_next = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
getTmpString(// Return values.
|
||||
char *&str,
|
||||
|
|
|
|||
Loading…
Reference in New Issue