liberty memory management

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2026-02-04 18:33:04 -07:00
parent c7f4bb3bb3
commit 33e480a6c1
53 changed files with 2314 additions and 2370 deletions

View File

@ -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()) {

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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 *

View File

@ -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

View File

@ -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_; }

View File

@ -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,

View File

@ -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_; }

View File

@ -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];
};

View File

@ -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*>;

View File

@ -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;

View File

@ -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_;

View File

@ -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,

View File

@ -192,6 +192,8 @@ char *
makeTmpString(std::string &str);
bool
isTmpString(const char *str);
void
deleteTmpStrings();
////////////////////////////////////////////////////////////////

View File

@ -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 &current_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_;

View File

@ -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];

View File

@ -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();

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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);
}
////////////////////////////////////////////////////////////////

View File

@ -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;
}

View File

@ -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:

View File

@ -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)
{
}

View File

@ -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

View File

@ -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_;
};

View File

@ -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");
}

View File

@ -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

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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())

View File

@ -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++;
}
}

View File

@ -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++;

View File

@ -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,

View File

@ -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_, " ");

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -254,6 +254,7 @@ deleteAllMemory()
deleteDelayCalcs();
PortDirection::destroy();
deleteLiberty();
deleteTmpStrings();
}
////////////////////////////////////////////////////////////////

View File

@ -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);

View File

@ -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);
}

View File

@ -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,

View File

@ -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);

View File

@ -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,