diff --git a/dcalc/ArcDcalcWaveforms.cc b/dcalc/ArcDcalcWaveforms.cc index 16595a28..b927bf1a 100644 --- a/dcalc/ArcDcalcWaveforms.cc +++ b/dcalc/ArcDcalcWaveforms.cc @@ -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(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()) { diff --git a/dcalc/CcsCeffDelayCalc.cc b/dcalc/CcsCeffDelayCalc.cc index e068a73d..14b3e639 100644 --- a/dcalc/CcsCeffDelayCalc.cc +++ b/dcalc/CcsCeffDelayCalc.cc @@ -530,12 +530,13 @@ CcsCeffDelayCalc::drvrWaveform() } } TableAxisPtr drvr_time_axis = make_shared(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(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(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 diff --git a/dcalc/GraphDelayCalc.cc b/dcalc/GraphDelayCalc.cc index f75883c9..e94b3c8b 100644 --- a/dcalc/GraphDelayCalc.cc +++ b/dcalc/GraphDelayCalc.cc @@ -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 diff --git a/dcalc/PrimaDelayCalc.cc b/dcalc/PrimaDelayCalc.cc index 188d533d..835d02c6 100644 --- a/dcalc/PrimaDelayCalc.cc +++ b/dcalc/PrimaDelayCalc.cc @@ -960,8 +960,8 @@ PrimaDelayCalc::watchWaveform(const Pin *pin) { FloatSeq &voltages = watch_pin_values_[pin]; TableAxisPtr time_axis = make_shared(TableAxisVariable::time, - new FloatSeq(times_)); - Table1 waveform(new FloatSeq(voltages), time_axis); + FloatSeq(times_)); + Table waveform(new FloatSeq(voltages), time_axis); return waveform; } diff --git a/dcalc/PrimaDelayCalc.hh b/dcalc/PrimaDelayCalc.hh index a5f402c7..361b23a4 100644 --- a/dcalc/PrimaDelayCalc.hh +++ b/dcalc/PrimaDelayCalc.hh @@ -46,7 +46,7 @@ using MatrixSd = Eigen::SparseMatrix; using PinLMap = std::map; using WatchPinValuesMap = std::map; -using Waveform = Table1; +using Waveform = Table; ArcDelayCalc * makePrimaDelayCalc(StaState *sta); diff --git a/graph/Graph.i b/graph/Graph.i index da7be0ee..ed9ad710 100644 --- a/graph/Graph.i +++ b/graph/Graph.i @@ -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 * diff --git a/include/sta/ContainerHelpers.hh b/include/sta/ContainerHelpers.hh index 49268ce8..abc87ffb 100644 --- a/include/sta/ContainerHelpers.hh +++ b/include/sta/ContainerHelpers.hh @@ -143,8 +143,8 @@ struct find_return }; -// 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 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 auto -findKey(const AssocContainer* c, +findKey(const AssocContainer *c, typename AssocContainer::key_type key) -> typename find_return::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 +auto +findKeyValue(const AssocContainer& c, + typename AssocContainer::key_type key) + -> const typename find_return::type & +{ + auto it = c.find(key); + if (it != c.end()) { + if constexpr (has_mapped_type::value) + return it->second; + else + return *it; + } + static const typename find_return::type empty{}; + return empty; +} + +// Find an value reference in a reference to a contaiiner of objects. +// Return exists. template void findKeyValue(const AssocContainer& c, @@ -205,7 +228,7 @@ findKeyValue(const AssocContainer& c, } if constexpr (has_mapped_type::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 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 auto findKeyValuePtr(AssocContainer& c, @@ -252,7 +280,27 @@ findKeyValuePtr(AssocContainer& c, return nullptr; if constexpr (has_mapped_type::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 +auto +findKeyValuePtr(const AssocContainer& c, + typename AssocContainer::key_type key) + -> const typename find_return::type* +{ + auto it = c.find(key); + if (it == c.end()) + return nullptr; + + if constexpr (has_mapped_type::value) + // map return &it->second; else // set diff --git a/include/sta/FuncExpr.hh b/include/sta/FuncExpr.hh index 3f537f52..b32cf023 100644 --- a/include/sta/FuncExpr.hh +++ b/include/sta/FuncExpr.hh @@ -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_; } diff --git a/include/sta/InternalPower.hh b/include/sta/InternalPower.hh index 408e946b..f1f0df4c 100644 --- a/include/sta/InternalPower.hh +++ b/include/sta/InternalPower.hh @@ -24,58 +24,46 @@ #pragma once +#include +#include +#include + #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, 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 &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 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, diff --git a/include/sta/LeakagePower.hh b/include/sta/LeakagePower.hh index 18f886c6..f14c8db2 100644 --- a/include/sta/LeakagePower.hh +++ b/include/sta/LeakagePower.hh @@ -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_; } diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index c89a5a66..41f6d493 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -24,11 +24,13 @@ #pragma once +#include #include #include #include #include #include +#include #include #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; +// 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; using TableTemplateSeq = std::vector; -using BusDclMap = std::map; -using BusDclSeq = std::vector; -using ScaleFactorsMap = std::map; -using WireloadMap = std::map; -using WireloadSelectionMap = std::map; -using OperatingConditionsMap = std::map; -using PortToSequentialMap = std::map; +using BusDclMap = std::map; +using BusDclSeq = std::vector; +using ScaleFactorsMap = std::map; +using WireloadMap = std::map; +using WireloadSelectionMap = std::map; +using OperatingConditionsMap = std::map; +using PortToSequentialMap = std::map; using TimingArcSetSeq = std::vector; using TimingArcSetSet = std::set; -using LibertyPortPairTimingArcMap = std::map; -using InternalPowerSeq = std::vector; -using PortInternalPowerMap = std::map; -using LeakagePowerSeq = std::vector; -using LibertyPortTimingArcMap = std::map; +using InternalPowerSeq = std::vector; +using InternalPowerPtrSeq = std::vector; +using InternalPowerIndexSeq = std::vector; +using PortInternalPowerMap = std::map; +using LeakagePowerSeq = std::vector; using ScaledCellMap = std::map; using ScaledPortMap = std::map; -using ModeDefMap = std::map; -using ModeValueMap = std::map; -using LatchEnableMap = std::map; -using LatchEnableSeq = std::vector; -using OcvDerateMap = std::map; -using InternalPowerAttrsSeq = std::vector; +using ModeDefMap = std::map; +using ModeValueMap = std::map; +using LatchEnableIndexMap = std::map; +using LatchEnableSeq = std::vector; +using OcvDerateMap = std::map; using SupplyVoltageMap = std::map; -using DriverWaveformMap = std::map; +using DriverWaveformMap = std::map; using SceneSeq = std::vector; 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 &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 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]; }; diff --git a/include/sta/LibertyClass.hh b/include/sta/LibertyClass.hh index 1d200a76..5436f480 100644 --- a/include/sta/LibertyClass.hh +++ b/include/sta/LibertyClass.hh @@ -68,7 +68,7 @@ class StatetableRow; using LibertyLibrarySeq = std::vector; using LibertyCellSeq = std::vector; -using SequentialSeq = std::vector; +using SequentialSeq = std::vector; using LibertyCellEquivMap = std::map; using LibertyPortSeq = std::vector; using LibertyPortSet = std::set; diff --git a/include/sta/Sdc.hh b/include/sta/Sdc.hh index 441db5d6..31b363bd 100644 --- a/include/sta/Sdc.hh +++ b/include/sta/Sdc.hh @@ -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; diff --git a/include/sta/Sequential.hh b/include/sta/Sequential.hh index 1923c270..67b62f3f 100644 --- a/include/sta/Sequential.hh +++ b/include/sta/Sequential.hh @@ -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_; diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index f5056ee0..e01b12e3 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -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, diff --git a/include/sta/StringUtil.hh b/include/sta/StringUtil.hh index 9523670b..c222d53b 100644 --- a/include/sta/StringUtil.hh +++ b/include/sta/StringUtil.hh @@ -192,6 +192,8 @@ char * makeTmpString(std::string &str); bool isTmpString(const char *str); +void +deleteTmpStrings(); //////////////////////////////////////////////////////////////// diff --git a/include/sta/TableModel.hh b/include/sta/TableModel.hh index a392e7d6..1d08d751 100644 --- a/include/sta/TableModel.hh +++ b/include/sta/TableModel.hh @@ -24,8 +24,9 @@ #pragma once -#include +#include #include +#include #include #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; -using FloatTable = std::vector; -using Table1Seq = std::vector; -using Waveform = Table1; +using FloatTable = std::vector; +// Sequence of 1D tables (order 1). +using Table1Seq = std::vector; +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 delay_model_; + std::array, EarlyLate::index_count> delay_sigma_models_; + std::unique_ptr slew_model_; + std::array, EarlyLate::index_count> slew_sigma_models_; ReceiverModelPtr receiver_model_; - OutputWaveforms *output_waveforms_; + std::unique_ptr 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 model_; + std::array, 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 capacitance_models_; + std::vector capacitance_models_; }; // Two dimensional (slew/cap) table of one dimensional time/current tables. @@ -496,7 +423,7 @@ public: TableAxisPtr cap_axis, const RiseFall *rf, Table1Seq ¤t_waveforms, - Table1 *ref_times); + Table ref_times); ~OutputWaveforms(); const RiseFall *rf() const { return rf_; } const TableAxis *slewAxis() const { return slew_axis_.get(); } @@ -523,18 +450,18 @@ public: float cap); static bool checkAxes(const TableTemplate *tbl_template); - Table1 currentWaveform(float slew, - float cap); + Table currentWaveform(float slew, + float cap); // Waveform closest to slew/cap; no interpolation. - const Table1 *currentWaveformRaw(float slew, - float cap); - Table1 voltageWaveform(float in_slew, - float load_cap); + const Table *currentWaveformRaw(float slew, + float cap); + Table voltageWaveform(float in_slew, + float load_cap); // Waveform closest to slew/cap; no interpolation. - const Table1 *voltageWaveformRaw(float slew, - float cap); - Table1 voltageCurrentWaveform(float slew, - float cap); + const Table *voltageWaveformRaw(float slew, + float cap); + Table voltageCurrentWaveform(float slew, + float cap); // V/I for last segment of min slew/max cap. float finalResistance(); @@ -563,10 +490,10 @@ private: // Column. TableAxisPtr cap_axis_; const RiseFall *rf_; - Table1Seq current_waveforms_; // from liberty + Table1Seq current_waveforms_; // from liberty (1D tables) Table1Seq voltage_waveforms_; Table1Seq voltage_currents_; - Table1 *ref_times_; + Table ref_times_; float vdd_; static constexpr size_t voltage_waveform_step_count_ = 100; }; @@ -577,7 +504,7 @@ public: DriverWaveform(const std::string &name, TablePtr waveforms); const char *name() const { return name_.c_str(); } - Table1 waveform(float slew); + Table waveform(float slew); private: std::string name_; diff --git a/include/sta/TimingArc.hh b/include/sta/TimingArc.hh index 080cf84d..347e37f1 100644 --- a/include/sta/TimingArc.hh +++ b/include/sta/TimingArc.hh @@ -25,6 +25,7 @@ #pragma once #include +#include #include #include @@ -39,7 +40,6 @@ class WireTimingArc; class GateTableModel; class Scene; -using TimingArcIndex = int; using TimingArcSeq = std::vector; using ScaledTimingModelMap = std::map; @@ -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]; diff --git a/liberty/EquivCells.cc b/liberty/EquivCells.cc index c39553ec..f081435b 100644 --- a/liberty/EquivCells.cc +++ b/liberty/EquivCells.cc @@ -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(); diff --git a/liberty/FuncExpr.cc b/liberty/FuncExpr.cc index 41faa2f6..38f3faea 100644 --- a/liberty/FuncExpr.cc +++ b/liberty/FuncExpr.cc @@ -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 diff --git a/liberty/InternalPower.cc b/liberty/InternalPower.cc index 407b152e..11492bf4 100644 --- a/liberty/InternalPower.cc +++ b/liberty/InternalPower.cc @@ -24,6 +24,8 @@ #include "InternalPower.hh" +#include + #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 &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 &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 &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, diff --git a/liberty/LeakagePower.cc b/liberty/LeakagePower.cc index 3ff8c5ac..07e8b7ce 100644 --- a/liberty/LeakagePower.cc +++ b/liberty/LeakagePower.cc @@ -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_) diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index a95d7a14..a6e7be96 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -92,15 +92,12 @@ LibertyLibrary::LibertyLibrary(const char *name, ocv_arc_depth_(0.0), default_ocv_derate_(nullptr), buffers_(nullptr), - inverters_(nullptr), - driver_waveform_default_(nullptr) + inverters_(nullptr) { // Scalar templates are builtin. for (int i = 0; i != table_template_type_count; i++) { TableTemplateType type = static_cast(i); - TableTemplate *scalar_template = new TableTemplate("scalar", nullptr, - nullptr, nullptr); - addTableTemplate(scalar_template, type); + makeTableTemplate("scalar", type); } for (auto rf_index : RiseFall::rangeIndex()) { @@ -114,27 +111,17 @@ LibertyLibrary::LibertyLibrary(const char *name, LibertyLibrary::~LibertyLibrary() { - deleteContents(bus_dcls_); - for (int i = 0; i < table_template_type_count; i++) - deleteContents(template_maps_[i]); - deleteContents(scale_factors_map_); delete scale_factors_; for (auto rf_index : RiseFall::rangeIndex()) { TableModel *model = wire_slew_degradation_tbls_[rf_index]; delete model; } - deleteContents(operating_conditions_); - deleteContents(wireloads_); - deleteContents(wire_load_selections_); delete units_; - // Also deletes default_ocv_derate_ - deleteContents(ocv_derate_map_); + // default_ocv_derate_ points into ocv_derate_map_; no separate delete delete buffers_; delete inverters_; - deleteContents(driver_waveform_map_); - delete driver_waveform_default_; } LibertyCell * @@ -194,39 +181,47 @@ LibertyLibrary::setDelayModelType(DelayModelType type) delay_model_type_ = type; } -void -LibertyLibrary::addBusDcl(BusDcl *bus_dcl) +BusDcl * +LibertyLibrary::makeBusDcl(std::string name, + int from, + int to) { - bus_dcls_[bus_dcl->name()] = bus_dcl; + std::string key = name; + auto [it, inserted] = bus_dcls_.try_emplace(std::move(key), std::move(name), from, to); + return &it->second; } BusDcl * LibertyLibrary::findBusDcl(const char *name) const { - return findKey(bus_dcls_, name); + auto it = bus_dcls_.find(name); + return it != bus_dcls_.end() ? const_cast(&it->second) : nullptr; } BusDclSeq LibertyLibrary::busDcls() const { BusDclSeq dcls; - for (auto [name, dcl] : bus_dcls_) - dcls.push_back(dcl); + for (auto &[key, dcl] : bus_dcls_) + dcls.push_back(const_cast(&dcl)); return dcls; } -void -LibertyLibrary::addTableTemplate(TableTemplate *tbl_template, - TableTemplateType type) +TableTemplate * +LibertyLibrary::makeTableTemplate(std::string name, + TableTemplateType type) { - template_maps_[int(type)][tbl_template->name()] = tbl_template; + std::string key = name; + auto [it, inserted] = template_maps_[int(type)].try_emplace( + std::move(key), std::move(name), type); + return &it->second; } TableTemplate * LibertyLibrary::findTableTemplate(const char *name, TableTemplateType type) { - return findKey(template_maps_[int(type)], name); + return findKeyValuePtr(template_maps_[int(type)], name); } TableTemplateSeq @@ -234,12 +229,21 @@ LibertyLibrary::tableTemplates() const { TableTemplateSeq tbl_templates; for (int type = 0; type < table_template_type_count; type++) { - for (auto [name, tbl_template] : template_maps_[type]) - tbl_templates.push_back(tbl_template); + for (auto &[key, tbl_template] : template_maps_[type]) + tbl_templates.push_back(const_cast(&tbl_template)); } return tbl_templates; } +TableTemplateSeq +LibertyLibrary::tableTemplates(TableTemplateType type) const +{ + TableTemplateSeq tbl_templates; + for (auto &[key, tbl_template] : template_maps_[int(type)]) + tbl_templates.push_back(const_cast(&tbl_template)); + return tbl_templates; +} + void LibertyLibrary::setNominalProcess(float process) { @@ -264,16 +268,17 @@ LibertyLibrary::setScaleFactors(ScaleFactors *scales) scale_factors_ = scales; } -void -LibertyLibrary::addScaleFactors(ScaleFactors *scales) +ScaleFactors * +LibertyLibrary::makeScaleFactors(const char *name) { - scale_factors_map_[scales->name()] = scales; + auto [it, inserted] = scale_factors_map_.emplace(std::string(name), name); + return &it->second; } ScaleFactors * LibertyLibrary::findScaleFactors(const char *name) { - return scale_factors_map_[name]; + return findKeyValuePtr(scale_factors_map_, std::string(name)); } float @@ -562,50 +567,55 @@ LibertyLibrary::setDefaultOutputPinRes(const RiseFall *rf, default_output_pin_res_.setValue(rf, value); } -void -LibertyLibrary::addWireload(Wireload *wireload) +Wireload * +LibertyLibrary::makeWireload(std::string name) { - wireloads_[wireload->name()] = wireload; + std::string key = name; + auto [it, inserted] = wireloads_.try_emplace( + std::move(key), name.c_str(), this); + return &it->second; } -Wireload * +const Wireload * LibertyLibrary::findWireload(const char *name) const { - return findKey(wireloads_, name); + return findKeyValuePtr(wireloads_, name); } void -LibertyLibrary::setDefaultWireload(Wireload *wireload) +LibertyLibrary::setDefaultWireload(const Wireload *wireload) { default_wire_load_ = wireload; } -Wireload * +const Wireload * LibertyLibrary::defaultWireload() const { return default_wire_load_; } -void -LibertyLibrary::addWireloadSelection(WireloadSelection *selection) +WireloadSelection * +LibertyLibrary::makeWireloadSelection(std::string name) { - wire_load_selections_[selection->name()] = selection; + std::string key = name; + auto [it, inserted] = wire_load_selections_.try_emplace(std::move(key), name.c_str()); + return &it->second; } -WireloadSelection * +const WireloadSelection * LibertyLibrary::findWireloadSelection(const char *name) const { - return findKey(wire_load_selections_, name); + return findKeyValuePtr(wire_load_selections_, name); } -WireloadSelection * +const WireloadSelection * LibertyLibrary::defaultWireloadSelection() const { return default_wire_load_selection_; } void -LibertyLibrary::setDefaultWireloadSelection(WireloadSelection *selection) +LibertyLibrary::setDefaultWireloadSelection(const WireloadSelection *selection) { default_wire_load_selection_ = selection; } @@ -622,16 +632,19 @@ LibertyLibrary::setDefaultWireloadMode(WireloadMode mode) default_wire_load_mode_ = mode; } -void -LibertyLibrary::addOperatingConditions(OperatingConditions *op_cond) +OperatingConditions * +LibertyLibrary::makeOperatingConditions(std::string name) { - operating_conditions_[op_cond->name()] = op_cond; + std::string key = name; + auto [it, inserted] = operating_conditions_.try_emplace( + std::move(key), name.c_str()); + return &it->second; } OperatingConditions * LibertyLibrary::findOperatingConditions(const char *name) { - return findKey(operating_conditions_, name); + return findKeyValuePtr(operating_conditions_, name); } OperatingConditions * @@ -848,15 +861,18 @@ LibertyLibrary::setDefaultOcvDerate(OcvDerate *derate) } OcvDerate * -LibertyLibrary::findOcvDerate(const char *derate_name) +LibertyLibrary::makeOcvDerate(std::string name) { - return findKey(ocv_derate_map_, derate_name); + std::string key = name; + auto [it, inserted] = ocv_derate_map_.try_emplace(std::move(key), std::move(name)); + return &it->second; } -void -LibertyLibrary::addOcvDerate(OcvDerate *derate) +OcvDerate * +LibertyLibrary::findOcvDerate(const char *derate_name) { - ocv_derate_map_[derate->name()] = derate; + auto it = ocv_derate_map_.find(derate_name); + return it != ocv_derate_map_.end() ? &it->second : nullptr; } void @@ -892,18 +908,18 @@ LibertyLibrary::supplyExists(const char *supply_name) const DriverWaveform * LibertyLibrary::findDriverWaveform(const char *name) { - return driver_waveform_map_[name]; + auto it = driver_waveform_map_.find(name); + if (it != driver_waveform_map_.end()) + return &it->second; + return nullptr; } -void -LibertyLibrary::addDriverWaveform(DriverWaveform *driver_waveform) +DriverWaveform * +LibertyLibrary::makeDriverWaveform(const std::string &name, + TablePtr waveforms) { - if (driver_waveform->name()) - driver_waveform_map_[driver_waveform->name()] = driver_waveform; - else { - delete driver_waveform_default_; - driver_waveform_default_ = driver_waveform; - } + auto it = driver_waveform_map_.emplace(name, DriverWaveform(name, waveforms)); + return &it.first->second; } //////////////////////////////////////////////////////////////// @@ -961,24 +977,11 @@ LibertyCell::LibertyCell(LibertyLibrary *library, LibertyCell::~LibertyCell() { - deleteContents(mode_defs_); - deleteContents(latch_enables_); - deleteContents(timing_arc_sets_); - deleteContents(port_timing_arc_set_map_); - deleteContents(timing_arc_set_from_map_); - deleteContents(timing_arc_set_to_map_); - deleteInternalPowerAttrs(); - deleteContents(internal_powers_); - deleteContents(leakage_powers_); - - deleteContents(sequentials_); delete statetable_; - deleteContents(bus_dcls_); deleteContents(scaled_cells_); - deleteContents(ocv_derate_map_); delete test_cell_; } @@ -1025,17 +1028,17 @@ LibertyCell::setHasInternalPorts(bool has_internal) } ModeDef * -LibertyCell::makeModeDef(const char *name) +LibertyCell::makeModeDef(std::string name) { - ModeDef *mode = new ModeDef(name); - mode_defs_[mode->name()] = mode; - return mode; + std::string key = name; + auto [it, inserted] = mode_defs_.try_emplace(std::move(key), std::move(name)); + return &it->second; } -ModeDef * -LibertyCell::findModeDef(const char *name) +const ModeDef * +LibertyCell::findModeDef(const char *name) const { - return findKey(mode_defs_, name); + return findKeyValuePtr(mode_defs_, name); } void @@ -1044,16 +1047,21 @@ LibertyCell::setScaleFactors(ScaleFactors *scale_factors) scale_factors_ = scale_factors; } -void -LibertyCell::addBusDcl(BusDcl *bus_dcl) +BusDcl * +LibertyCell::makeBusDcl(std::string name, + int from, + int to) { - bus_dcls_[bus_dcl->name()] = bus_dcl; + std::string key = name; + auto [it, inserted] = bus_dcls_.try_emplace(std::move(key), std::move(name), from, to); + return &it->second; } BusDcl * LibertyCell::findBusDcl(const char *name) const { - return findKey(bus_dcls_, name); + auto it = bus_dcls_.find(name); + return it != bus_dcls_.end() ? const_cast(&it->second) : nullptr; } void @@ -1240,57 +1248,48 @@ LibertyCell::bufferPorts(// Return values. } } -unsigned -LibertyCell::addTimingArcSet(TimingArcSet *arc_set) +TimingArcSet * +LibertyCell::makeTimingArcSet(LibertyPort *from, + LibertyPort *to, + LibertyPort *related_out, + const TimingRole *role, + TimingArcAttrsPtr attrs) { - int set_index = timing_arc_sets_.size(); + size_t set_index = timing_arc_sets_.size(); + TimingArcSet *arc_set = new TimingArcSet(this, from, to, related_out, role, + attrs, set_index); timing_arc_sets_.push_back(arc_set); - - LibertyPort *from = arc_set->from(); - LibertyPort *to = arc_set->to(); - const TimingRole *role = arc_set->role(); - if (role == TimingRole::regClkToQ() - || role == TimingRole::latchEnToQ()) { - from->setIsRegClk(true); - to->setIsRegOutput(true); - } - if (role->isTimingCheck()) - from->setIsCheckClk(true); - return set_index; + return arc_set; } void -LibertyCell::addInternalPower(InternalPower *power) +LibertyCell::makeInternalPower(LibertyPort *port, + LibertyPort *related_port, + const std::string &related_pg_pin, + const std::shared_ptr &when, + InternalPowerModels &models) { - internal_powers_.push_back(power); - port_internal_powers_[power->port()].push_back(power); + internal_powers_.emplace_back(port, related_port, related_pg_pin, + when, models); + port_internal_powers_[port].push_back(internal_powers_.size() - 1); } -const InternalPowerSeq & -LibertyCell::internalPowers(const LibertyPort *port) +InternalPowerPtrSeq +LibertyCell::internalPowers(const LibertyPort *port) const { - return port_internal_powers_[port]; + InternalPowerPtrSeq result; + const InternalPowerIndexSeq &pwrs = findKeyValue(port_internal_powers_,port); + for (size_t idx : pwrs) + result.push_back(&internal_powers_[idx]); + return result; } void -LibertyCell::addInternalPowerAttrs(InternalPowerAttrs *attrs) +LibertyCell::makeLeakagePower(LibertyPort *related_pg_port, + FuncExpr *when, + float power) { - internal_power_attrs_.push_back(attrs); -} - -void -LibertyCell::deleteInternalPowerAttrs() -{ - for (InternalPowerAttrs *attrs : internal_power_attrs_) { - attrs->deleteContents(); - delete attrs; - } -} - -void -LibertyCell::addLeakagePower(LeakagePower *power) -{ - leakage_powers_.push_back(power); + leakage_powers_.emplace_back(this, related_pg_port, when, power); } void @@ -1315,7 +1314,6 @@ LibertyCell::finish(bool infer_latches, Debug *debug) { translatePresetClrCheckRoles(); - makeTimingArcMap(report); makeTimingArcPortMaps(); findDefaultCondArcs(); makeLatchEnables(report, debug); @@ -1328,14 +1326,14 @@ LibertyCell::findDefaultCondArcs() { for (auto [port_pair, sets] : port_timing_arc_set_map_) { bool has_cond_arcs = false; - for (auto set : *sets) { + for (auto set : sets) { if (set->cond()) { has_cond_arcs = true; break; } } if (has_cond_arcs) { - for (auto set : *sets) { + for (auto set : sets) { if (!set->cond()) set->setIsCondDefault(true); } @@ -1367,92 +1365,60 @@ LibertyCell::translatePresetClrCheckRoles() } } -void -LibertyCell::makeTimingArcMap(Report *) -{ - // Filter duplicate timing arcs, keeping the later definition. - for (auto arc_set : timing_arc_sets_) - // The last definition will be left in the set. - timing_arc_set_set_.insert(arc_set); - - // Prune the arc sets not in the map. - int j = 0; - for (size_t i = 0; i < timing_arc_sets_.size(); i++) { - TimingArcSet *arc_set = timing_arc_sets_[i]; - TimingArcSet *match = findKey(timing_arc_set_set_, arc_set); - if (match != arc_set) { - // Unfortunately these errors are common in some brain damaged - // libraries. - // report->warn("cell %s/%s has duplicate %s -> %s %s timing groups.", - // library_->name(), - // name_, - // match->from()->name(), - // match->to()->name(), - // match->role()->asString()); - delete arc_set; - } - else - // Shift arc sets down to fill holes left by removed duplicates. - timing_arc_sets_[j++] = arc_set; - } - timing_arc_sets_.resize(j); - - if (timing_arc_sets_.size() != timing_arc_sets_.size()) - criticalError(1121, "timing arc count mismatch"); -} - void LibertyCell::makeTimingArcPortMaps() { - for (auto arc_set : timing_arc_sets_) { + for (TimingArcSet *arc_set : timing_arc_sets_) { LibertyPort *from = arc_set->from(); LibertyPort *to = arc_set->to(); - LibertyPortPair port_pair(from, to); - TimingArcSetSeq *sets = - findKey(port_timing_arc_set_map_, port_pair); - if (sets == nullptr) { - // First arc set for from/to ports. - sets = new TimingArcSetSeq; - port_timing_arc_set_map_[port_pair] = sets; + if (from && to) { + LibertyPortPair from_to_pair(from, to); + TimingArcSetSeq &sets = port_timing_arc_set_map_[from_to_pair]; + sets.push_back(arc_set); } - sets->push_back(arc_set); - sets = findKey(timing_arc_set_from_map_, from); - if (sets == nullptr) { - sets = new TimingArcSetSeq; - timing_arc_set_from_map_[from] = sets; - } - sets->push_back(arc_set); + LibertyPortPair from_pair(from, nullptr); + TimingArcSetSeq &from_sets = port_timing_arc_set_map_[from_pair]; + from_sets.push_back(arc_set); - sets = findKey(timing_arc_set_to_map_, to); - if (sets == nullptr) { - sets = new TimingArcSetSeq; - timing_arc_set_to_map_[to] = sets; + LibertyPortPair to_pair(nullptr, to); + TimingArcSetSeq &to_sets = port_timing_arc_set_map_[to_pair]; + to_sets.push_back(arc_set); + + const TimingRole *role = arc_set->role(); + if (role == TimingRole::regClkToQ() + || role == TimingRole::latchEnToQ()) { + from->setIsRegClk(true); + if (to) + to->setIsRegOutput(true); } - sets->push_back(arc_set); + if (role->isTimingCheck()) + from->setIsCheckClk(true); + + timing_arc_set_set_.insert(arc_set); } } +const TimingArcSetSeq & +LibertyCell::timingArcSetsFrom(const LibertyPort *from) const +{ + return timingArcSets(from, nullptr); +} + +const TimingArcSetSeq & +LibertyCell::timingArcSetsTo(const LibertyPort *to) const +{ + return timingArcSets(nullptr, to); +} + const TimingArcSetSeq & LibertyCell::timingArcSets(const LibertyPort *from, const LibertyPort *to) const { - TimingArcSetSeq *arc_sets = nullptr; - if (from && to) { - LibertyPortPair port_pair(from, to); - arc_sets = findKey(port_timing_arc_set_map_, port_pair); - } - else if (from) - arc_sets = findKey(timing_arc_set_from_map_, from); - else if (to) - arc_sets = findKey(timing_arc_set_to_map_, to); - - if (arc_sets) - return *arc_sets; - else { - static TimingArcSetSeq null_set; - return null_set; - } + static const TimingArcSetSeq null_set; + const LibertyPortPair port_pair(from, to); + auto itr = port_timing_arc_set_map_.find(port_pair); + return (itr == port_timing_arc_set_map_.end()) ? null_set : itr->second; } TimingArcSet * @@ -1462,9 +1428,9 @@ LibertyCell::findTimingArcSet(TimingArcSet *arc_set) const } TimingArcSet * -LibertyCell::findTimingArcSet(unsigned arc_set_index) const +LibertyCell::findTimingArcSet(size_t index) const { - return timing_arc_sets_[arc_set_index]; + return timing_arc_sets_[index]; } size_t @@ -1476,8 +1442,8 @@ LibertyCell::timingArcSetCount() const bool LibertyCell::hasTimingArcs(LibertyPort *port) const { - return findKey(timing_arc_set_from_map_, port) - || findKey(timing_arc_set_to_map_, port); + return port_timing_arc_set_map_.contains(LibertyPortPair(port, nullptr)) + || port_timing_arc_set_map_.contains(LibertyPortPair(nullptr, port)); } void @@ -1511,20 +1477,23 @@ LibertyCell::makeSequential(int size, LibertyPort *out_inv_bit = output_inv; if (output_inv && output_inv->hasMembers()) out_inv_bit = output_inv->findLibertyMember(bit); - Sequential *seq = new Sequential(is_register, clk_bit, data_bit, - clear_bit,preset_bit, - clr_preset_out, clr_preset_out_inv, - out_bit, out_inv_bit); - sequentials_.push_back(seq); - port_to_seq_map_[seq->output()] = seq; - port_to_seq_map_[seq->outputInv()] = seq; + sequentials_.emplace_back(is_register, clk_bit, data_bit, + clear_bit, preset_bit, + clr_preset_out, clr_preset_out_inv, + out_bit, out_inv_bit); + size_t idx = sequentials_.size() - 1; + port_to_seq_map_[sequentials_.back().output()] = idx; + port_to_seq_map_[sequentials_.back().outputInv()] = idx; } } Sequential * LibertyCell::outputPortSequential(LibertyPort *port) { - return findKey(port_to_seq_map_, port); + auto it = port_to_seq_map_.find(port); + if (it != port_to_seq_map_.end()) + return &sequentials_[it->second]; + return nullptr; } bool @@ -1667,51 +1636,22 @@ LibertyCell::setOcvDerate(OcvDerate *derate) } OcvDerate * -LibertyCell::findOcvDerate(const char *derate_name) +LibertyCell::makeOcvDerate(std::string name) { - return findKey(ocv_derate_map_, derate_name); + std::string key = name; + auto [it, inserted] = ocv_derate_map_.try_emplace(std::move(key), std::move(name)); + return &it->second; } -void -LibertyCell::addOcvDerate(OcvDerate *derate) +OcvDerate * +LibertyCell::findOcvDerate(const char *derate_name) { - ocv_derate_map_[derate->name()] = derate; + auto it = ocv_derate_map_.find(derate_name); + return it != ocv_derate_map_.end() ? &it->second : nullptr; } //////////////////////////////////////////////////////////////// -// 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_; -}; - LatchEnable::LatchEnable(LibertyPort *data, LibertyPort *enable, const RiseFall *enable_edge, @@ -1744,7 +1684,7 @@ LibertyCell::makeLatchEnables(Report *report, if (en_to_q->role() == TimingRole::latchEnToQ()) { LibertyPort *en = en_to_q->from(); LibertyPort *q = en_to_q->to(); - for (TimingArcSet *d_to_q : timingArcSets(nullptr, q)) { + for (TimingArcSet *d_to_q : timingArcSetsTo(q)) { if (d_to_q->role() == TimingRole::latchDtoQ() && condMatch(en_to_q, d_to_q)) { LibertyPort *d = d_to_q->from(); @@ -1842,19 +1782,19 @@ LibertyCell::findLatchEnableFunc(const LibertyPort *d, const LibertyPort *en, const RiseFall *en_rf) const { - for (auto seq : sequentials_) { - if (seq->isLatch() - && seq->data() - && seq->data()->hasPort(d) - && seq->clock() - && seq->clock()->hasPort(en)) { - FuncExpr *en_func = seq->clock(); + for (const auto &seq : sequentials_) { + if (seq.isLatch() + && seq.data() + && seq.data()->hasPort(d) + && seq.clock() + && seq.clock()->hasPort(en)) { + FuncExpr *en_func = seq.clock(); TimingSense en_sense = en_func->portTimingSense(en); if ((en_sense == TimingSense::positive_unate && en_rf == RiseFall::rise()) || (en_sense == TimingSense::negative_unate && en_rf == RiseFall::fall())) - return seq->clock(); + return seq.clock(); } } return nullptr; @@ -1871,11 +1811,11 @@ LibertyCell::makeLatchEnable(LibertyPort *d, Debug *debug) { FuncExpr *en_func = findLatchEnableFunc(d, en, en_rf); - LatchEnable *latch_enable = new LatchEnable(d, en, en_rf, en_func, q, - d_to_q, en_to_q, setup_check); - latch_enables_.push_back(latch_enable); - latch_d_to_q_map_[d_to_q] = latch_enable; - latch_check_map_[setup_check] = latch_enable; + latch_enables_.emplace_back(d, en, en_rf, en_func, q, d_to_q, en_to_q, + setup_check); + size_t idx = latch_enables_.size() - 1; + latch_d_to_q_map_[d_to_q] = idx; + latch_check_map_[setup_check] = idx; d->setIsLatchData(true); debugPrint(debug, "liberty_latch", 1, "latch %s -> %s | %s %s -> %s | %s %s -> %s setup", @@ -1887,7 +1827,7 @@ LibertyCell::makeLatchEnable(LibertyPort *d, en->name(), setup_check->arcs()[0]->fromEdge()->asRiseFall()->shortName(), q->name()); - return latch_enable; + return &latch_enables_.back(); } void @@ -1896,13 +1836,12 @@ LibertyCell::inferLatchRoles(Report *report, { if (hasInferedRegTimingArcs()) { // Hunt down potential latch D/EN/Q triples. - std::set latch_enables; for (TimingArcSet *en_to_q : timingArcSets()) { // Locate potential d->q arcs from reg clk->q arcs. if (en_to_q->role() == TimingRole::regClkToQ()) { LibertyPort *en = en_to_q->from(); LibertyPort *q = en_to_q->to(); - for (TimingArcSet *d_to_q : timingArcSets(nullptr, q)) { + for (TimingArcSet *d_to_q : timingArcSetsTo(q)) { // Look for combinational d->q arcs. const TimingRole *d_to_q_role = d_to_q->role(); if (((d_to_q_role == TimingRole::combinational() @@ -1935,11 +1874,12 @@ LibertyCell::latchEnable(const TimingArcSet *d_to_q_set, const FuncExpr *&enable_func, const RiseFall *&enable_edge) const { - LatchEnable *latch_enable = findKey(latch_d_to_q_map_, d_to_q_set); - if (latch_enable) { - enable_port = latch_enable->enable(); - enable_func = latch_enable->enableFunc(); - enable_edge = latch_enable->enableEdge(); + auto it = latch_d_to_q_map_.find(d_to_q_set); + if (it != latch_d_to_q_map_.end()) { + const LatchEnable &latch_enable = latch_enables_[it->second]; + enable_port = latch_enable.enable(); + enable_func = latch_enable.enableFunc(); + enable_edge = latch_enable.enableEdge(); } else { enable_port = nullptr; @@ -1951,9 +1891,9 @@ LibertyCell::latchEnable(const TimingArcSet *d_to_q_set, const RiseFall * LibertyCell::latchCheckEnableEdge(TimingArcSet *check_set) { - LatchEnable *latch_enable = findKey(latch_check_map_, check_set); - if (latch_enable) - return latch_enable->enableEdge(); + auto it = latch_check_map_.find(check_set); + if (it != latch_check_map_.end()) + return latch_enables_[it->second].enableEdge(); else return nullptr; } @@ -2108,20 +2048,12 @@ LibertyPort::LibertyPort(LibertyCell *cell, liberty_port_ = this; min_pulse_width_[RiseFall::riseIndex()] = 0.0; min_pulse_width_[RiseFall::fallIndex()] = 0.0; - for (auto from_rf_index : RiseFall::rangeIndex()) { - for (auto to_rf_index : RiseFall::rangeIndex()) { - for (auto mm_index : MinMax::rangeIndex()) - clk_tree_delay_[from_rf_index][to_rf_index][mm_index] = nullptr; - } - } } LibertyPort::~LibertyPort() { - if (function_) - function_->deleteSubexprs(); - if (tristate_enable_) - tristate_enable_->deleteSubexprs(); + delete function_; + delete tristate_enable_; delete scaled_ports_; } @@ -2324,7 +2256,7 @@ LibertyPort::driveResistance(const RiseFall *rf, { float max_drive = min_max->initValue(); bool found_drive = false; - for (TimingArcSet *arc_set : liberty_cell_->timingArcSets(nullptr, this)) { + for (TimingArcSet *arc_set : liberty_cell_->timingArcSetsTo(this)) { if (!arc_set->role()->isTimingCheck()) { for (TimingArc *arc : arc_set->arcs()) { if (rf == nullptr @@ -2358,7 +2290,7 @@ LibertyPort::intrinsicDelay(const RiseFall *rf, { ArcDelay max_delay = min_max->initValue(); bool found_delay = false; - for (TimingArcSet *arc_set : liberty_cell_->timingArcSets(nullptr, this)) { + for (TimingArcSet *arc_set : liberty_cell_->timingArcSetsTo(this)) { if (!arc_set->role()->isTimingCheck()) { for (TimingArc *arc : arc_set->arcs()) { if (rf == nullptr @@ -2801,6 +2733,8 @@ LibertyPort::setDriverWaveform(DriverWaveform *driver_waveform, driver_waveform_[rf->index()] = driver_waveform; } +//////////////////////////////////////////////////////////////// + RiseFallMinMax LibertyPort::clockTreePathDelays() const { @@ -2820,12 +2754,8 @@ LibertyPort::clkTreeDelays1() const for (const RiseFall *from_rf : RiseFall::range()) { for (const RiseFall *to_rf : RiseFall::range()) { for (const MinMax *min_max : MinMax::range()) { - const TableModel *model = - clk_tree_delay_[from_rf->index()][to_rf->index()][min_max->index()]; - if (model) { - float delay = model->findValue(0.0, 0.0, 0.0); - delays.setValue(from_rf, min_max, delay); - } + float delay = clkTreeDelay(0.0, from_rf, to_rf, min_max); + delays.setValue(from_rf, min_max, delay); } } } @@ -2837,11 +2767,7 @@ LibertyPort::clkTreeDelay(float in_slew, const RiseFall *rf, const MinMax *min_max) const { - const TableModel *model = clk_tree_delay_[rf->index()][rf->index()][min_max->index()]; - if (model) - return model->findValue(in_slew, 0.0, 0.0); - else - return 0.0; + return clkTreeDelay(in_slew, rf, rf, min_max); } float @@ -2850,22 +2776,23 @@ LibertyPort::clkTreeDelay(float in_slew, const RiseFall *to_rf, const MinMax *min_max) const { - const TableModel *model = - clk_tree_delay_[from_rf->index()][to_rf->index()][min_max->index()]; - if (model) - return model->findValue(in_slew, 0.0, 0.0); - else - return 0.0; + for (TimingArcSet *arc_set : liberty_cell_->timingArcSetsTo(this)) { + if ((arc_set->role() == TimingRole::clockTreePathMin() + && min_max == MinMax::min()) + || (arc_set->role() == TimingRole::clockTreePathMax() + && min_max == MinMax::max())) { + const TimingArc *arc = arc_set->arcTo(to_rf); + if (arc->fromEdge()->asRiseFall() == from_rf) { + const GateTableModel *gate_model = dynamic_cast(arc->model()); + if (gate_model) + return gate_model->delayModel()->findValue(in_slew, 0.0, 0.0); + } + } + } + return 0.0; } -void -LibertyPort::setClkTreeDelay(const TableModel *model, - const RiseFall *from_rf, - const RiseFall *to_rf, - const MinMax *min_max) -{ - clk_tree_delay_[from_rf->index()][to_rf->index()][min_max->index()] = model; -} +//////////////////////////////////////////////////////////////// void LibertyPort::setMemberFlag(bool value, @@ -2941,11 +2868,13 @@ bool LibertyPortPairLess::operator()(const LibertyPortPair &pair1, const LibertyPortPair &pair2) const { - ObjectId id1 = pair1.first ? pair1.first->id() : 0; - ObjectId id2 = pair2.first ? pair2.first->id() : 0; - return id1 < id2 - || (id1 == id2 - && pair1.second->id() < pair2.second->id()); + ObjectId id11 = pair1.first ? pair1.first->id() : 0; + ObjectId id12 = pair1.second ? pair1.second->id() : 0; + ObjectId id21 = pair2.first ? pair2.first->id() : 0; + ObjectId id22 = pair2.second ? pair2.second->id() : 0; + return id11 < id21 + || (id11 == id21 + && id12 < id22); } //////////////////////////////////////////////////////////////// @@ -2974,10 +2903,10 @@ LibertyPortMemberIterator::next() //////////////////////////////////////////////////////////////// -BusDcl::BusDcl(const char *name, +BusDcl::BusDcl(std::string name, int from, int to) : - name_(name), + name_(std::move(name)), from_(from), to_(to) { @@ -2985,47 +2914,50 @@ BusDcl::BusDcl(const char *name, //////////////////////////////////////////////////////////////// -ModeDef::ModeDef(const char *name) : - name_(name) +ModeDef::ModeDef(std::string name) : + name_(std::move(name)) { } -ModeDef::~ModeDef() -{ - deleteContents(values_); -} - ModeValueDef * ModeDef::defineValue(const char *value, FuncExpr *cond, const char *sdf_cond) { - ModeValueDef *val_def = new ModeValueDef(value, cond, sdf_cond); - values_[val_def->value()] = val_def; - return val_def; + std::string key = value; + std::string sdf = sdf_cond ? std::string(sdf_cond) : std::string(); + auto [it, inserted] = values_.try_emplace(key, key, cond, std::move(sdf)); + return &it->second; } -ModeValueDef * -ModeDef::findValueDef(const char *value) +const ModeValueDef * +ModeDef::findValueDef(const char *value) const { - return values_[value]; + return findKeyValuePtr(values_, value); } //////////////////////////////////////////////////////////////// -ModeValueDef::ModeValueDef(const char *value, +ModeValueDef::ModeValueDef(std::string value, FuncExpr *cond, - const char *sdf_cond) : - value_(value), + std::string sdf_cond) : + value_(std::move(value)), cond_(cond), - sdf_cond_(sdf_cond ? sdf_cond : "") + sdf_cond_(std::move(sdf_cond)) { } +ModeValueDef::ModeValueDef(ModeValueDef &&other) noexcept : + value_(std::move(other.value_)), + cond_(other.cond_), + sdf_cond_(std::move(other.sdf_cond_)) +{ + other.cond_ = nullptr; +} + ModeValueDef::~ModeValueDef() { - if (cond_) - cond_->deleteSubexprs(); + delete cond_; } void @@ -3035,26 +2967,38 @@ ModeValueDef::setCond(FuncExpr *cond) } void -ModeValueDef::setSdfCond(const char *sdf_cond) +ModeValueDef::setSdfCond(std::string sdf_cond) { - sdf_cond_ = sdf_cond; + sdf_cond_ = std::move(sdf_cond); } //////////////////////////////////////////////////////////////// -TableTemplate::TableTemplate(const char *name) : - name_(name), +TableTemplate::TableTemplate(std::string name) : + name_(std::move(name)), + type_(TableTemplateType::delay), axis1_(nullptr), axis2_(nullptr), axis3_(nullptr) { } -TableTemplate::TableTemplate(const char *name, +TableTemplate::TableTemplate(std::string name, + TableTemplateType type) : + name_(std::move(name)), + type_(type), + axis1_(nullptr), + axis2_(nullptr), + axis3_(nullptr) +{ +} + +TableTemplate::TableTemplate(std::string name, TableAxisPtr axis1, TableAxisPtr axis2, TableAxisPtr axis3) : - name_(name), + name_(std::move(name)), + type_(TableTemplateType::delay), axis1_(axis1), axis2_(axis2), axis3_(axis3) @@ -3062,9 +3006,9 @@ TableTemplate::TableTemplate(const char *name, } void -TableTemplate::setName(const char *name) +TableTemplate::setName(std::string name) { - name_ = name; + name_ = std::move(name); } void @@ -3299,16 +3243,16 @@ ScaleFactors::print() } TestCell::TestCell(LibertyLibrary *library, - const char *name, - const char *filename) : - LibertyCell(library, name, filename) + std::string name, + std::string filename) : + LibertyCell(library, name.c_str(), filename.c_str()) { } //////////////////////////////////////////////////////////////// -OcvDerate::OcvDerate(const char *name) : - name_(name) +OcvDerate::OcvDerate(std::string name) : + name_(std::move(name)) { for (auto el_index : EarlyLate::rangeIndex()) { for (auto rf_index : RiseFall::rangeIndex()) { @@ -3320,7 +3264,6 @@ OcvDerate::OcvDerate(const char *name) : OcvDerate::~OcvDerate() { - stringDelete(name_); } const Table * diff --git a/liberty/Liberty.i b/liberty/Liberty.i index 10bb9963..96223170 100644 --- a/liberty/Liberty.i +++ b/liberty/Liberty.i @@ -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 diff --git a/liberty/LibertyBuilder.cc b/liberty/LibertyBuilder.cc index 5afedc09..b20d8c62 100644 --- a/liberty/LibertyBuilder.cc +++ b/liberty/LibertyBuilder.cc @@ -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(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 diff --git a/liberty/LibertyBuilder.hh b/liberty/LibertyBuilder.hh index 8511b108..dacbbb41 100644 --- a/liberty/LibertyBuilder.hh +++ b/liberty/LibertyBuilder.hh @@ -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, diff --git a/liberty/LibertyExt.cc b/liberty/LibertyExt.cc index 10a214b1..d45a7420 100644 --- a/liberty/LibertyExt.cc +++ b/liberty/LibertyExt.cc @@ -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(attrs)->frob(); + const char *frob = static_cast(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); } //////////////////////////////////////////////////////////////// diff --git a/liberty/LibertyLex.ll b/liberty/LibertyLex.ll index ccf2aea5..6df7d07b 100644 --- a/liberty/LibertyLex.ll +++ b/liberty/LibertyLex.ll @@ -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(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(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(yytext); return token::STRING; } @@ -134,14 +134,14 @@ EOL \r?\n \" { BEGIN(INITIAL); - yylval->string = stringCopy(token_.c_str()); + yylval->emplace(token_); return token::STRING; } {EOL} { error("unterminated string constant"); BEGIN(INITIAL); - yylval->string = stringCopy(token_.c_str()); + yylval->emplace(token_); return token::STRING; } diff --git a/liberty/LibertyParse.yy b/liberty/LibertyParse.yy index 7cc067e3..7423c4fe 100644 --- a/liberty/LibertyParse.yy +++ b/liberty/LibertyParse.yy @@ -24,6 +24,9 @@ %{ #include +#include +#include +#include #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 STRING KEYWORD +%token FLOAT %left '+' '-' '|' %left '*' '/' '&' %left '^' %left '!' -%token FLOAT -%token STRING KEYWORD - -%type statement complex_attr simple_attr variable group file -%type attr_values -%type attr_value -%type string expr expr_term expr_term1 volt_expr -%type expr_op volt_op +%type statement complex_attr simple_attr variable group file +%type attr_values +%type attr_value +%type string expr expr_term expr_term1 volt_expr +%type 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: diff --git a/liberty/LibertyParser.cc b/liberty/LibertyParser.cc index 4dff3a40..9cf52702 100644 --- a/liberty/LibertyParser.cc +++ b/liberty/LibertyParser.cc @@ -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) { } diff --git a/liberty/LibertyParser.hh b/liberty/LibertyParser.hh index 9b1fce2c..e27d859a 100644 --- a/liberty/LibertyParser.hh +++ b/liberty/LibertyParser.hh @@ -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; @@ -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: diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index 5a2ca07d..f2676531 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -59,7 +59,7 @@ using std::make_shared; using std::string; static void -scaleFloats(FloatSeq *floats, +scaleFloats(FloatSeq &floats, float scale); LibertyLibrary * @@ -703,7 +703,7 @@ LibertyReader::endLibraryAttrs(LibertyGroup *group) // These attributes reference named groups in the library so // wait until the end of the library to resolve them. if (default_wireload_) { - Wireload *wireload = library_->findWireload(default_wireload_); + const Wireload *wireload = library_->findWireload(default_wireload_); if (wireload) library_->setDefaultWireload(wireload); else @@ -713,7 +713,7 @@ LibertyReader::endLibraryAttrs(LibertyGroup *group) } if (default_wireload_selection_) { - WireloadSelection *selection = + const WireloadSelection *selection = library_->findWireloadSelection(default_wireload_selection_); if (selection) library_->setDefaultWireloadSelection(selection); @@ -818,17 +818,17 @@ LibertyReader::parseUnits(LibertyAttr *attr, float &scale_var, Unit *unit) { - string units = getAttrString(attr); - if (!units.empty()) { + const char *units = getAttrString(attr); + if (units) { // Unit format is . // Find the multiplier digits. - string units = getAttrString(attr); - size_t mult_end = units.find_first_not_of("0123456789"); + string units1 = units; + size_t mult_end = units1.find_first_not_of("0123456789"); float mult = 1.0F; string scale_suffix; - if (mult_end != units.npos) { - string unit_mult = units.substr(0, mult_end); - scale_suffix = units.substr(mult_end); + if (mult_end != units1.npos) { + string unit_mult = units1.substr(0, mult_end); + scale_suffix = units1.substr(mult_end); if (unit_mult == "1") mult = 1.0F; else if (unit_mult == "10") @@ -875,7 +875,7 @@ void LibertyReader::visitCapacitiveLoadUnit(LibertyAttr *attr) { if (library_) { - if (attr->isComplex()) { + if (attr->isComplexAttr()) { LibertyAttrValueSeq *values = attr->values(); if (values->size() == 2) { LibertyAttrValue *value = (*values)[0]; @@ -898,10 +898,10 @@ LibertyReader::visitCapacitiveLoadUnit(LibertyAttr *attr) if (valid) { value = (*values)[1]; if (value->isString()) { - const char *suffix = value->stringValue(); - if (stringEqual(suffix, "ff")) + const std::string suffix = value->stringValue(); + if (stringEqual(suffix.c_str(), "ff")) cap_scale_ = scale * 1E-15F; - else if (stringEqual(suffix, "pf")) + else if (stringEqual(suffix.c_str(), "pf")) cap_scale_ = scale * 1E-12F; else libWarn(1154, attr, "capacitive_load_units are not ff or pf."); @@ -979,12 +979,12 @@ void LibertyReader::visitVoltageMap(LibertyAttr *attr) { if (library_) { - if (attr->isComplex()) { + if (attr->isComplexAttr()) { LibertyAttrValueSeq *values = attr->values(); if (values->size() >= 1) { LibertyAttrValue *value = (*values)[0]; if (value->isString()) { - const char *supply_name = value->stringValue(); + const std::string &supply_name = value->stringValue(); if (values->size() == 2) { value = (*values)[1]; bool valid = false; @@ -1004,7 +1004,7 @@ LibertyReader::visitVoltageMap(LibertyAttr *attr) } if (valid) - library_->addSupplyVoltage(supply_name, voltage); + library_->addSupplyVoltage(supply_name.c_str(), voltage); else libWarn(1166, attr, "voltage_map voltage is not a float."); } @@ -1418,8 +1418,7 @@ LibertyReader::beginTableTemplate(LibertyGroup *group, if (library_) { const char *name = group->firstName(); if (name) { - tbl_template_ = new TableTemplate(name); - library_->addTableTemplate(tbl_template_, type); + tbl_template_ = library_->makeTableTemplate(name, type); } else libWarn(1175, group, "table template missing name."); @@ -1431,7 +1430,9 @@ LibertyReader::beginTableTemplate(LibertyGroup *group, void LibertyReader::clearAxisValues() { - axis_values_[0] = axis_values_[1] = axis_values_[2] = nullptr; + axis_values_[0].clear(); + axis_values_[1].clear(); + axis_values_[2].clear(); } void @@ -1457,30 +1458,31 @@ LibertyReader::makeAxis(int index, LibertyGroup *group) { TableAxisVariable axis_var = axis_var_[index]; - FloatSeq *axis_values = axis_values_[index]; if (axis_var != TableAxisVariable::unknown) { - if (axis_values) { + FloatSeq values; + if (!axis_values_[index].empty()) { const Units *units = library_->units(); float scale = tableVariableUnit(axis_var, units)->scale(); - scaleFloats(axis_values, scale); + values = std::move(axis_values_[index]); + scaleFloats(values, scale); } - return make_shared(axis_var, axis_values); + return make_shared(axis_var, std::move(values)); } - else if (axis_values) { + else if (!axis_values_[index].empty()) { libWarn(1176, group, "missing variable_%d attribute.", index + 1); - delete axis_values; - axis_values_[index] = nullptr; + axis_values_[index].clear(); } // No warning for missing index_xx attributes because they are not required. return nullptr; } static void -scaleFloats(FloatSeq *floats, float scale) +scaleFloats(FloatSeq &floats, + float scale) { - size_t count = floats->size(); + size_t count = floats.size(); for (size_t i = 0; i < count; i++) - (*floats)[i] *= scale; + floats[i] *= scale; } void @@ -1538,22 +1540,21 @@ LibertyReader::visitIndex(int index, LibertyAttr *attr) { if (tbl_template_ - // Ignore index_xx in ecsm_waveform groups. + // Ignore index_* in ecsm_waveform groups. && !in_ecsm_waveform_) { - FloatSeq *axis_values = readFloatSeq(attr, 1.0F); - if (axis_values) { - if (axis_values->empty()) - libWarn(1177, attr, "missing table index values."); - else { - float prev = (*axis_values)[0]; - for (size_t i = 1; i < axis_values->size(); i++) { - float value = (*axis_values)[i]; - if (value <= prev) - libWarn(1178, attr, "non-increasing table index values."); - prev = value; - } + FloatSeq axis_values = readFloatSeq(attr, 1.0F); + if (axis_values.empty()) + libWarn(1177, attr, "missing table index values."); + else { + // Check monotonicity of the values. + float prev = axis_values[0]; + for (size_t i = 1; i < axis_values.size(); i++) { + float value = axis_values[i]; + if (value <= prev) + libWarn(1178, attr, "non-increasing table index values."); + prev = value; } - axis_values_[index] = axis_values; + axis_values_[index] = std::move(axis_values); } } } @@ -1573,11 +1574,10 @@ LibertyReader::endType(LibertyGroup *group) const char *name = group->firstName(); if (name) { if (type_bit_from_exists_ && type_bit_to_exists_) { - BusDcl *bus_dcl = new BusDcl(name, type_bit_from_, type_bit_to_); if (cell_) - cell_->addBusDcl(bus_dcl); + cell_->makeBusDcl(name, type_bit_from_, type_bit_to_); else if (library_) - library_->addBusDcl(bus_dcl); + library_->makeBusDcl(name, type_bit_from_, type_bit_to_); } else { if (!type_bit_from_exists_) @@ -1610,8 +1610,7 @@ LibertyReader::beginScalingFactors(LibertyGroup *group) const char *name = group->firstName(); if (name) { save_scale_factors_ = scale_factors_; - scale_factors_ = new ScaleFactors(name); - library_->addScaleFactors(scale_factors_); + scale_factors_ = library_->makeScaleFactors(name); } else libWarn(1182, group, "scaling_factors do not have a name."); @@ -1631,7 +1630,7 @@ LibertyReader::visitScaleFactorSuffix(LibertyAttr *attr) ScaleFactorType type = ScaleFactorType::unknown; const RiseFall *rf = nullptr; // Parse the attribute name. - TokenParser parser(attr->name(), "_"); + TokenParser parser(attr->name().c_str(), "_"); if (parser.hasNext()) parser.next(); if (parser.hasNext()) { @@ -1669,7 +1668,7 @@ LibertyReader::visitScaleFactorPrefix(LibertyAttr *attr) ScaleFactorType type = ScaleFactorType::unknown; const RiseFall *rf = nullptr; // Parse the attribute name. - TokenParser parser(attr->name(), "_"); + TokenParser parser(attr->name().c_str(), "_"); if (parser.hasNext()) parser.next(); if (parser.hasNext()) { @@ -1710,7 +1709,7 @@ LibertyReader::visitScaleFactorHiLow(LibertyAttr *attr) const char *type_name = nullptr; const char *tr_name = nullptr; // Parse the attribute name. - TokenParser parser(attr->name(), "_"); + TokenParser parser(attr->name().c_str(), "_"); if (parser.hasNext()) parser.next(); if (parser.hasNext()) { @@ -1749,7 +1748,7 @@ LibertyReader::visitScaleFactor(LibertyAttr *attr) const char *pvt_name = nullptr; const char *type_name = nullptr; // Parse the attribute name. - TokenParser parser(attr->name(), " "); + TokenParser parser(attr->name().c_str(), " "); if (parser.hasNext()) parser.next(); if (parser.hasNext()) { @@ -1778,10 +1777,8 @@ LibertyReader::beginOpCond(LibertyGroup *group) { if (library_) { const char *name = group->firstName(); - if (name) { - op_cond_ = new OperatingConditions(name); - library_->addOperatingConditions(op_cond_); - } + if (name) + op_cond_ = library_->makeOperatingConditions(name); else libWarn(1183, group, "operating_conditions missing name."); } @@ -1848,10 +1845,8 @@ LibertyReader::beginWireload(LibertyGroup *group) { if (library_) { const char *name = group->firstName(); - if (name) { - wireload_ = new Wireload(name, library_); - library_->addWireload(wireload_); - } + if (name) + wireload_ = library_->makeWireload(name); } else libWarn(1184, group, "wire_load missing name."); @@ -1906,10 +1901,8 @@ LibertyReader::beginWireloadSelection(LibertyGroup *group) { if (library_) { const char *name = group->firstName(); - if (name) { - wireload_selection_ = new WireloadSelection(name); - library_->addWireloadSelection(wireload_selection_); - } + if (name) + wireload_selection_ = library_->makeWireloadSelection(name); } else libWarn(1186, group, "wire_load_selection missing name."); @@ -1925,7 +1918,7 @@ void LibertyReader::visitWireloadFromArea(LibertyAttr *attr) { if (wireload_selection_) { - if (attr->isComplex()) { + if (attr->isComplexAttr()) { LibertyAttrValueSeq *values = attr->values(); if (values->size() == 3) { LibertyAttrValue *value = (*values)[0]; @@ -1937,14 +1930,14 @@ LibertyReader::visitWireloadFromArea(LibertyAttr *attr) value = (*values)[2]; if (value->isString()) { - const char *wireload_name = value->stringValue(); + const std::string &wireload_name = value->stringValue(); const Wireload *wireload = - library_->findWireload(wireload_name); + library_->findWireload(wireload_name.c_str()); if (wireload) wireload_selection_->addWireloadFromArea(min_area, max_area, wireload); else - libWarn(1187, attr, "wireload %s not found.", wireload_name); + libWarn(1187, attr, "wireload %s not found.", wireload_name.c_str()); } else libWarn(1188, attr, @@ -2077,7 +2070,7 @@ LibertyReader::makeScalarCheckModel(float value, ScaleFactorType scale_factor_type, const RiseFall *rf) { - TablePtr table = make_shared(value); + TablePtr table = make_shared(value); TableTemplate *tbl_template = library_->findTableTemplate("scalar", TableTemplateType::delay); TableModel *table_model = new TableModel(table, tbl_template, @@ -2103,7 +2096,6 @@ LibertyReader::makeInternalPowers(PortGroup *port_group) for (InternalPowerGroup *power_group : port_group->internalPowerGroups()) { for (LibertyPort *port : *port_group->ports()) makeInternalPowers(port, power_group); - cell_->addInternalPowerAttrs(power_group); } } @@ -2134,7 +2126,7 @@ LibertyReader::makeCellSequential(SequentialGroup *seq) clk_expr = parseFunc(clk, clk_attr, line); if (clk_expr && clk_expr->checkSize(size)) { libWarn(1196, line, "%s %s bus width mismatch.", type, clk_attr); - clk_expr->deleteSubexprs(); + delete clk_expr; clk_expr = nullptr; } } @@ -2145,7 +2137,7 @@ LibertyReader::makeCellSequential(SequentialGroup *seq) data_expr = parseFunc(data, data_attr, line); if (data_expr && data_expr->checkSize(size)) { libWarn(1197, line, "%s %s bus width mismatch.", type, data_attr); - data_expr->deleteSubexprs(); + delete data_expr; data_expr = nullptr; } } @@ -2155,7 +2147,7 @@ LibertyReader::makeCellSequential(SequentialGroup *seq) clr_expr = parseFunc(clr, "clear", line); if (clr_expr && clr_expr->checkSize(size)) { libWarn(1198, line, "%s %s bus width mismatch.", type, "clear"); - clr_expr->deleteSubexprs(); + delete clr_expr; clr_expr = nullptr; } } @@ -2165,7 +2157,7 @@ LibertyReader::makeCellSequential(SequentialGroup *seq) preset_expr = parseFunc(preset, "preset", line); if (preset_expr && preset_expr->checkSize(size)) { libWarn(1199, line, "%s %s bus width mismatch.", type, "preset"); - preset_expr->deleteSubexprs(); + delete preset_expr; preset_expr = nullptr; } } @@ -2177,14 +2169,10 @@ LibertyReader::makeCellSequential(SequentialGroup *seq) checkLatchEnableSense(clk_expr, line); // The expressions used in the sequentials are copied by bitSubExpr. - if (clk_expr) - clk_expr->deleteSubexprs(); - if (data_expr) - data_expr->deleteSubexprs(); - if (clr_expr) - clr_expr->deleteSubexprs(); - if (preset_expr) - preset_expr->deleteSubexprs(); + delete clk_expr; + delete data_expr; + delete clr_expr; + delete preset_expr; } void @@ -2245,6 +2233,15 @@ void LibertyReader::makeLeakagePowers() { for (LeakagePowerGroup *power_group : leakage_powers_) { +<<<<<<< +======= + LibertyPort *related_pg_pin = + cell_->findLibertyPort(power_group->relatedPgPin().c_str()); + cell_->makeLeakagePower(related_pg_pin, power_group->when(), power_group->power()); + delete power_group; + } + leakage_powers_.clear(); +>>>>>>> LibertyPort *related_pg_pin = cell_->findLibertyPort(power_group->relatedPgPin().c_str()); LeakagePower *leakage = new LeakagePower(cell_, related_pg_pin, power_group->when(), @@ -2274,15 +2271,8 @@ LibertyReader::parseCellFuncs() { for (LibertyFunc *func : cell_funcs_) { FuncExpr *expr = parseFunc(func->expr(), func->attrName(), func->line()); - if (func->invert() && expr) { - if (expr->op() == FuncExpr::Op::not_) { - FuncExpr *inv = expr; - expr = expr->left(); - delete inv; - } - else - expr = FuncExpr::makeNot(expr); - } + if (func->invert() && expr) + expr = expr->invert(); if (expr) func->setFunc()(expr); delete func; @@ -2441,7 +2431,7 @@ void TimingGroup::makeTableModels(LibertyCell *cell, LibertyReader *reader) { - for (auto rf : RiseFall::range()) { + for (const RiseFall *rf : RiseFall::range()) { int rf_index = rf->index(); TableModel *delay = cell_[rf_index]; TableModel *transition = transition_[rf_index]; @@ -2475,6 +2465,9 @@ TimingGroup::makeTableModels(LibertyCell *cell, else if (constraint) attrs_->setModel(rf, new CheckTableModel(cell, constraint, constraint_sigma_[rf_index])); + cell_[rf_index] = nullptr; + transition_[rf_index] = nullptr; + constraint_[rf_index] = nullptr; } } @@ -2664,14 +2657,14 @@ LibertyReader::endReceiverCapacitanceRiseFall(LibertyGroup *group) { if (table_) { if (ReceiverModel::checkAxes(table_)) { - TableModel *table_model = new TableModel(table_, tbl_template_, - scale_factor_type_, rf_); if (receiver_model_ == nullptr) { receiver_model_ = make_shared(); if (timing_) timing_->setReceiverModel(receiver_model_); } - receiver_model_->setCapacitanceModel(table_model, index_, rf_); + receiver_model_->setCapacitanceModel(TableModel(table_, tbl_template_, + scale_factor_type_, rf_), + index_, rf_); } else libWarn(1219, group, "unsupported model axis."); @@ -2711,28 +2704,31 @@ LibertyReader::endOutputCurrentRiseFall(LibertyGroup *group) { if (timing_) { std::set slew_set, cap_set; - FloatSeq *slew_values = new FloatSeq; - FloatSeq *cap_values = new FloatSeq; + FloatSeq slew_values; + FloatSeq cap_values; for (OutputWaveform *waveform : output_currents_) { float slew = waveform->slew(); if (!slew_set.contains(slew)) { slew_set.insert(slew); - slew_values->push_back(slew); + slew_values.push_back(slew); } float cap = waveform->cap(); if (!cap_set.contains(cap)) { cap_set.insert(cap); - cap_values->push_back(cap); + cap_values.push_back(cap); } } sort(slew_values, std::less()); sort(cap_values, std::less()); - TableAxisPtr slew_axis = make_shared(TableAxisVariable::input_net_transition, - slew_values); - TableAxisPtr cap_axis = make_shared(TableAxisVariable::total_output_net_capacitance, - cap_values); - FloatSeq *ref_times = new FloatSeq(slew_values->size()); - Table1Seq current_waveforms(slew_axis->size() * cap_axis->size()); + size_t slew_size = slew_values.size(); + size_t cap_size = cap_values.size(); + TableAxisPtr slew_axis=make_shared(TableAxisVariable::input_net_transition, + std::move(slew_values)); + TableAxisPtr cap_axis = + make_shared(TableAxisVariable::total_output_net_capacitance, + std::move(cap_values)); + FloatSeq ref_times(slew_size); + Table1Seq current_waveforms(slew_size * cap_size); for (OutputWaveform *waveform : output_currents_) { size_t slew_index, cap_index; bool slew_exists, cap_exists; @@ -2741,17 +2737,17 @@ LibertyReader::endOutputCurrentRiseFall(LibertyGroup *group) if (slew_exists && cap_exists) { size_t index = slew_index * cap_axis->size() + cap_index; current_waveforms[index] = waveform->stealCurrents(); - (*ref_times)[slew_index] = waveform->referenceTime(); + ref_times[slew_index] = waveform->referenceTime(); } else libWarn(1221, group, "output current waveform %.2e %.2e not found.", waveform->slew(), waveform->cap()); } - Table1 *ref_time_tbl = new Table1(ref_times, slew_axis); + Table ref_time_tbl(std::move(ref_times), slew_axis); OutputWaveforms *output_current = new OutputWaveforms(slew_axis, cap_axis, rf_, current_waveforms, - ref_time_tbl); + std::move(ref_time_tbl)); timing_->setOutputWaveforms(rf_, output_current); deleteContents(output_currents_); } @@ -2781,28 +2777,26 @@ void LibertyReader::endVector(LibertyGroup *group) { if (timing_ && tbl_template_) { - FloatSeq *slew_values = axis_values_[0]; - FloatSeq *cap_values = axis_values_[1]; + TableAxisPtr slew_axis, cap_axis; // Canonicalize axis order. if (tbl_template_->axis1()->variable() == TableAxisVariable::input_net_transition) { - slew_values = axis_values_[0]; - cap_values = axis_values_[1]; + slew_axis = axis_[0]; + cap_axis = axis_[1]; } else { - slew_values = axis_values_[1]; - cap_values = axis_values_[0]; + slew_axis = axis_[1]; + cap_axis = axis_[0]; } - if (slew_values->size() == 1 && cap_values->size() == 1) { - // Convert 1x1xN Table3 to Table1. - float slew = (*slew_values)[0]; - float cap = (*cap_values)[0]; - Table3 *table3 = dynamic_cast(table_.get()); - FloatTable *values3 = table3->values3(); - // Steal the values. - FloatSeq *values = (*values3)[0]; - (*values3)[0] = nullptr; - Table1 *table1 = new Table1(values, axis_[2]); + if (slew_axis->size() == 1 && cap_axis->size() == 1) { + // Convert 1x1xN Table (order 3) to 1D Table. + float slew = slew_axis->axisValue(0); + float cap = cap_axis->axisValue(0); + Table *table_ptr = table_.get(); + FloatTable *values3 = table_ptr->values3(); + FloatSeq row = std::move((*values3)[0]); + values3->erase(values3->begin()); + Table *table1 = new Table(std::move(row), axis_[2]); OutputWaveform *waveform = new OutputWaveform(slew, cap, table1, reference_time_); output_currents_.push_back(waveform); } @@ -2837,9 +2831,7 @@ LibertyReader::endNormalizedDriverWaveform(LibertyGroup *group) if (table_->axis1()->variable() == TableAxisVariable::input_net_transition) { if (table_->axis2()->variable() == TableAxisVariable::normalized_voltage) { // Null driver_waveform_name_ means it is the default unnamed waveform. - DriverWaveform *driver_waveform = new DriverWaveform(driver_waveform_name_, - table_); - library_->addDriverWaveform(driver_waveform); + library_->makeDriverWaveform(driver_waveform_name_, table_); } else @@ -2896,15 +2888,18 @@ LibertyReader::makeInternalPowers(LibertyPort *port, } } else { + const std::string &related_pg_pin = power_group->relatedPgPin(); if (port->hasMembers()) { LibertyPortMemberIterator bit_iter(port); while (bit_iter.hasNext()) { LibertyPort *port_bit = bit_iter.next(); - builder_.makeInternalPower(cell_, port_bit, nullptr, power_group); + cell_->makeInternalPower(port_bit, nullptr, related_pg_pin, + power_group->when(), power_group->models()); } } else - builder_.makeInternalPower(cell_, port, nullptr, power_group); + cell_->makeInternalPower(port, nullptr, related_pg_pin, power_group->when(), + power_group->models()); } } @@ -2914,18 +2909,21 @@ LibertyReader::makeInternalPowers(LibertyPort *port, PortNameBitIterator &related_port_iter, InternalPowerGroup *power_group) { + const std::string &related_pg_pin = power_group->relatedPgPin(); + const auto &when = power_group->when(); + InternalPowerModels &models = power_group->models(); if (related_port_iter.size() == 1 && !port->hasMembers()) { // one -> one if (related_port_iter.hasNext()) { LibertyPort *related_port = related_port_iter.next(); - builder_.makeInternalPower(cell_, port, related_port, power_group); + cell_->makeInternalPower(port, related_port, related_pg_pin, when, models); } } else if (related_port_iter.size() > 1 && !port->hasMembers()) { // bus -> one while (related_port_iter.hasNext()) { LibertyPort *related_port = related_port_iter.next(); - builder_.makeInternalPower(cell_, port, related_port, power_group); + cell_->makeInternalPower(port, related_port, related_pg_pin, when, models); } } else if (related_port_iter.size() == 1 && port->hasMembers()) { @@ -2935,7 +2933,7 @@ LibertyReader::makeInternalPowers(LibertyPort *port, LibertyPortMemberIterator bit_iter(port); while (bit_iter.hasNext()) { LibertyPort *port_bit = bit_iter.next(); - builder_.makeInternalPower(cell_, port_bit, related_port, power_group); + cell_->makeInternalPower(port_bit, related_port, related_pg_pin, when, models); } } } @@ -2947,7 +2945,8 @@ LibertyReader::makeInternalPowers(LibertyPort *port, while (related_port_iter.hasNext() && to_iter.hasNext()) { LibertyPort *related_port_bit = related_port_iter.next(); LibertyPort *port_bit = to_iter.next(); - builder_.makeInternalPower(cell_, port_bit, related_port_bit, power_group); + cell_->makeInternalPower(port_bit, related_port_bit, related_pg_pin, + when, models); } } else @@ -2962,7 +2961,8 @@ LibertyReader::makeInternalPowers(LibertyPort *port, LibertyPortMemberIterator to_iter(port); while (to_iter.hasNext()) { LibertyPort *port_bit = to_iter.next(); - builder_.makeInternalPower(cell_, port_bit, related_port_bit, power_group); + cell_->makeInternalPower(port_bit, related_port_bit, related_pg_pin, + when, models); } } } @@ -3180,9 +3180,9 @@ LibertyReader::beginPin(LibertyGroup *group) ports_ = new LibertyPortSeq; for (LibertyAttrValue *param : *group->params()) { if (param->isString()) { - const char *port_name = param->stringValue(); - debugPrint(debug_, "liberty", 1, " port %s", port_name); - PortNameBitIterator port_iter(cell_, port_name, this, group->line()); + const std::string &port_name = param->stringValue(); + debugPrint(debug_, "liberty", 1, " port %s", port_name.c_str()); + PortNameBitIterator port_iter(cell_, port_name.c_str(), this, group->line()); while (port_iter.hasNext()) { LibertyPort *port = port_iter.next(); ports_->push_back(port); @@ -3198,7 +3198,7 @@ LibertyReader::beginPin(LibertyGroup *group) ports_ = new LibertyPortSeq; for (LibertyAttrValue *param : *group->params()) { if (param->isString()) { - const char *name = param->stringValue(); + const char *name = param->stringValue().c_str(); debugPrint(debug_, "liberty", 1, " port %s", name); LibertyPort *port = findPort(name); if (port == nullptr) @@ -3214,7 +3214,7 @@ LibertyReader::beginPin(LibertyGroup *group) // Multiple port names can share group def. for (LibertyAttrValue *param : *group->params()) { if (param->isString()) { - const char *name = param->stringValue(); + const char *name = param->stringValue().c_str(); debugPrint(debug_, "liberty", 1, " port %s", name); LibertyPort *port = makePort(cell_, name); ports_->push_back(port); @@ -3323,9 +3323,8 @@ LibertyReader::beginBusOrBundle(LibertyGroup *group) // Multiple port names can share group def. for (LibertyAttrValue *param : *group->params()) { if (param->isString()) { - const char *name = param->stringValue(); - if (name) - bus_names_.push_back(stringCopy(name)); + const string &name = param->stringValue(); + bus_names_.push_back(stringCopy(name.c_str())); } } ports_ = new LibertyPortSeq; @@ -3394,13 +3393,13 @@ void LibertyReader::visitMembers(LibertyAttr *attr) { if (cell_) { - if (attr->isComplex()) { + if (attr->isComplexAttr()) { for (const char *name : bus_names_) { debugPrint(debug_, "liberty", 1, " bundle %s", name); ConcretePortSeq *members = new ConcretePortSeq; for (LibertyAttrValue *value : *attr->values()) { if (value->isString()) { - const char *port_name = value->stringValue(); + const char *port_name = value->stringValue().c_str(); LibertyPort *port = findPort(port_name); if (port == nullptr) port = makePort(cell_, port_name); @@ -4054,7 +4053,7 @@ LibertyReader::seqPortNames(LibertyGroup *group, else { // in_port (ignored), out_port, out_port_inv out_name = group->secondName(); - out_inv_name = third_value->stringValue(); + out_inv_name = third_value->stringValue().c_str(); } } } @@ -4422,7 +4421,7 @@ void LibertyReader::visitMode(LibertyAttr *attr) { if (timing_) { - if (attr->isComplex()) { + if (attr->isComplexAttr()) { LibertyAttrValueSeq *values = attr->values(); if (values->size() == 2) { LibertyAttrValue *value = (*values)[0]; @@ -4624,7 +4623,7 @@ LibertyReader::beginTimingTableModel(LibertyGroup *group, beginTableModel(group, TableTemplateType::delay, rf, time_scale_, scale_factor_type); else - libWarn(1255, group, "%s group not in timing group.", group->firstName()); + libWarn(1255, group, "%s group not in timing group.", group->type().c_str()); } void @@ -4709,7 +4708,7 @@ void LibertyReader::makeTable(LibertyAttr *attr, float scale) { - if (attr->isComplex()) { + if (attr->isComplexAttr()) { makeTableAxis(0, attr); makeTableAxis(1, attr); makeTableAxis(2, attr); @@ -4717,80 +4716,67 @@ LibertyReader::makeTable(LibertyAttr *attr, // 3D table // Column index1*size(index2) + index2 // Row index3 - FloatTable *table = makeFloatTable(attr, - axis_[0]->size()*axis_[1]->size(), - axis_[2]->size(), scale); - table_ = make_shared(table, axis_[0], axis_[1], axis_[2]); + table_ = make_shared
(makeFloatTable(attr, + axis_[0]->size() * axis_[1]->size(), + axis_[2]->size(), scale), + axis_[0], axis_[1], axis_[2]); } else if (axis_[0] && axis_[1]) { // 2D table // Row variable1/axis[0] // Column variable2/axis[1] - FloatTable *table = makeFloatTable(attr, axis_[0]->size(), - axis_[1]->size(), scale); - table_ = make_shared(table, axis_[0], axis_[1]); + table_ = make_shared
(makeFloatTable(attr, axis_[0]->size(), + axis_[1]->size(), scale), + axis_[0], axis_[1]); } else if (axis_[0]) { // 1D table - FloatTable *table = makeFloatTable(attr, 1, axis_[0]->size(), scale); - FloatSeq *values = (*table)[0]; - delete table; - table_ = make_shared(values, axis_[0]); + FloatTable table = makeFloatTable(attr, 1, axis_[0]->size(), scale); + table_ = make_shared
(std::move(table[0]), axis_[0]); } else if (axis_[0] == nullptr && axis_[1] == nullptr && axis_[2] == nullptr) { // scalar - FloatTable *table = makeFloatTable(attr, 1, 1, scale); - float value = (*(*table)[0])[0]; - delete (*table)[0]; - delete table; - table_ = make_shared(value); + FloatTable table = makeFloatTable(attr, 1, 1, scale); + float value = table[0][0]; + table_ = make_shared
(value); } } else - libWarn(1257, attr, "%s is missing values.", attr->name()); + libWarn(1257, attr, "%s is missing values.", attr->name().c_str()); } -FloatTable * +FloatTable LibertyReader::makeFloatTable(LibertyAttr *attr, size_t rows, size_t cols, float scale) { - FloatTable *table = new FloatTable; - table->reserve(rows); + FloatTable table; + table.reserve(rows); for (LibertyAttrValue *value : *attr->values()) { - FloatSeq *row = new FloatSeq; - row->reserve(cols); - table->push_back(row); - if (value->isString()) { - const char *values_list = value->stringValue(); - parseStringFloatList(values_list, scale, row, attr); - } + FloatSeq row; + if (value->isString()) + row = parseStringFloatList(value->stringValue(), scale, attr); else if (value->isFloat()) - // Scalar value. - row->push_back(value->floatValue() * scale); + row.push_back(value->floatValue() * scale); else - libWarn(1258, attr, "%s is not a list of floats.", attr->name()); - if (row->size() != cols) { + libWarn(1258, attr, "%s is not a list of floats.", attr->name().c_str()); + if (row.size() != cols) { libWarn(1259, attr, "table row has %zu columns but axis has %zu.", - row->size(), + row.size(), cols); - // Fill out row columns with zeros. - for (size_t c = row->size(); c < cols; c++) - row->push_back(0.0); + for (size_t c = row.size(); c < cols; c++) + row.push_back(0.0); } + table.push_back(std::move(row)); } - if (table->size() != rows) { + if (table.size() != rows) { libWarn(1260, attr, "table has %zu rows but axis has %zu.", - table->size(), + table.size(), rows); - // Fill with zero'd rows. - for (size_t r = table->size(); r < rows; r++) { - FloatSeq *row = new FloatSeq; - table->push_back(row); - // Fill out row with zeros. - for (size_t c = row->size(); c < cols; c++) - row->push_back(0.0); + for (size_t r = table.size(); r < rows; r++) { + FloatSeq row(cols, 0.0); + table.push_back(std::move(row)); } } return table; @@ -4800,18 +4786,18 @@ void LibertyReader::makeTableAxis(int index, LibertyAttr *attr) { - if (axis_values_[index]) { + if (axis_[index] && !axis_values_[index].empty()) { TableAxisVariable var = axis_[index]->variable(); - FloatSeq *values = axis_values_[index]; const Units *units = library_->units(); float scale = tableVariableUnit(var, units)->scale(); + FloatSeq values = std::move(axis_values_[index]); scaleFloats(values, scale); - axis_[index] = make_shared(var, values); + axis_[index] = make_shared(var, std::move(values)); } - else if (axis_[index] && axis_[index]->values() == nullptr) { + else if (axis_[index] && axis_[index]->values().empty()) { libWarn(1344, attr, "Table axis and template missing values."); axis_[index] = nullptr; - axis_values_[index] = nullptr; + axis_values_[index].clear(); } } @@ -4825,9 +4811,9 @@ LibertyReader::beginLut(LibertyGroup *group) if (cell_) { for (LibertyAttrValue *param : *group->params()) { if (param->isString()) { - const char *names = param->stringValue(); + const std::string &names = param->stringValue(); // Parse space separated list of related port names. - TokenParser parser(names, " "); + TokenParser parser(names.c_str(), " "); while (parser.hasNext()) { char *name = parser.next(); if (name[0] != '\0') { @@ -4857,7 +4843,7 @@ LibertyReader::beginTestCell(LibertyGroup *group) else { string name = cell_->name(); name += "/test_cell"; - test_cell_ = new TestCell(cell_->libertyLibrary(), name.c_str(), + test_cell_ = new TestCell(cell_->libertyLibrary(), std::move(name), cell_->filename()); cell_->setTestCell(test_cell_); @@ -4956,7 +4942,9 @@ LibertyReader::visitWhen(LibertyAttr *attr) if (func) { InternalPowerGroup *internal_pwr = internal_power_; makeLibertyFunc(func, - [internal_pwr] (FuncExpr *expr) { internal_pwr->setWhen(expr);}, + [internal_pwr] (FuncExpr *expr) { + internal_pwr->setWhen(std::shared_ptr(expr)); + }, false, "when", attr); } } @@ -4992,15 +4980,15 @@ LibertyReader::visitSdfCond(LibertyAttr *attr) const char * LibertyReader::getAttrString(LibertyAttr *attr) { - if (attr->isSimple()) { + if (attr->isSimpleAttr()) { LibertyAttrValue *value = attr->firstValue(); if (value->isString()) - return value->stringValue(); + return value->stringValue().c_str(); else - libWarn(1266, attr, "%s attribute is not a string.", attr->name()); + libWarn(1266, attr, "%s attribute is not a string.", attr->name().c_str()); } else - libWarn(1267, attr, "%s is not a simple attribute.", attr->name()); + libWarn(1267, attr, "%s is not a simple attribute.", attr->name().c_str()); return nullptr; } @@ -5012,7 +5000,7 @@ LibertyReader::getAttrInt(LibertyAttr *attr, { value = 0; exists = false; - if (attr->isSimple()) { + if (attr->isSimpleAttr()) { LibertyAttrValue *attr_value = attr->firstValue(); if (attr_value->isFloat()) { float float_val = attr_value->floatValue(); @@ -5020,10 +5008,10 @@ LibertyReader::getAttrInt(LibertyAttr *attr, exists = true; } else - libWarn(1268, attr, "%s attribute is not an integer.",attr->name()); + libWarn(1268, attr, "%s attribute is not an integer.",attr->name().c_str()); } else - libWarn(1269, attr, "%s is not a simple attribute.", attr->name()); + libWarn(1269, attr, "%s is not a simple attribute.", attr->name().c_str()); } void @@ -5033,10 +5021,10 @@ LibertyReader::getAttrFloat(LibertyAttr *attr, bool &valid) { valid = false; - if (attr->isSimple()) + if (attr->isSimpleAttr()) getAttrFloat(attr, attr->firstValue(), value, valid); else - libWarn(1270, attr, "%s is not a simple attribute.", attr->name()); + libWarn(1270, attr, "%s is not a simple attribute.", attr->name().c_str()); } void @@ -5051,20 +5039,20 @@ LibertyReader::getAttrFloat(LibertyAttr *attr, value = attr_value->floatValue(); } else if (attr_value->isString()) { - const char *string = attr_value->stringValue(); + const std::string &str = attr_value->stringValue(); // See if attribute string is a variable. - variableValue(string, value, valid); + variableValue(str.c_str(), value, valid); if (!valid) { // For some reason area attributes for pads are quoted floats. // Check that the string is a valid double. char *end; - value = strtof(string, &end); + value = strtof(str.c_str(), &end); if ((*end && !isspace(*end)) // strtof support INF as a valid float. - || stringEqual(string, "inf")) + || str == "inf") libWarn(1271, attr, "%s value %s is not a float.", - attr->name(), - string); + attr->name().c_str(), + str.c_str()); valid = true; } } @@ -5080,85 +5068,94 @@ LibertyReader::getAttrFloat2(LibertyAttr *attr, bool &exists) { exists = false; - if (attr->isComplex()) { + if (attr->isComplexAttr()) { LibertyAttrValueSeq *values = attr->values(); if (values->size() == 2) { LibertyAttrValue *value = (*values)[0]; getAttrFloat(attr, value, value1, exists); if (!exists) - libWarn(1272, attr, "%s is not a float.", attr->name()); + libWarn(1272, attr, "%s is not a float.", attr->name().c_str()); value = (*values)[1]; getAttrFloat(attr, value, value2, exists); if (!exists) - libWarn(1273, attr, "%s is not a float.", attr->name()); + libWarn(1273, attr, "%s is not a float.", attr->name().c_str()); } else - libWarn(1274, attr, "%s requires 2 valules.", attr->name()); + libWarn(1274, attr, "%s requires 2 valules.", attr->name().c_str()); } else - libWarn(1345, attr, "%s requires 2 valules.", attr->name()); + libWarn(1345, attr, "%s requires 2 valules.", attr->name().c_str()); } // Parse string of comma separated floats. // Note that some brain damaged vendors (that used to "Think") are not // consistent about including the delimiters. -void -LibertyReader::parseStringFloatList(const char *float_list, +FloatSeq +LibertyReader::parseStringFloatList(const std::string &float_list, float scale, - FloatSeq *values, LibertyAttr *attr) { - const char *delimiters = ", "; - TokenParser parser(float_list, delimiters); - while (parser.hasNext()) { - char *token = parser.next(); + FloatSeq values; + const char *token = float_list.c_str(); + while (*token != '\0') { // Some (brain dead) libraries enclose floats in brackets. if (*token == '{') token++; char *end; float value = strtof(token, &end) * scale; if (end == token - || (end && !(*end == '\0' - || isspace(*end) - || strchr(delimiters, *end) != nullptr - || *end == '}'))) - libWarn(1275, attr, "%s is not a float.", token); - values->push_back(value); + || !(*end == '\0' + || isspace(*end) + || *end == ',' + || *end == '}')) { + std::string token_end = token; + if (end != token) { + token_end.clear(); + for (const char *t = token; t <= end; t++) + token_end += *t; + } + libWarn(1275, attr, "%s is not a float.", token_end.c_str()); + token += token_end.size(); + } + else { + values.push_back(value); + token = end; + } + while (*token == ',' || *token == ' ' || *token == '}') + token++; } + return values; } -FloatSeq * +FloatSeq LibertyReader::readFloatSeq(LibertyAttr *attr, float scale) { - FloatSeq *values = nullptr; - if (attr->isComplex()) { + FloatSeq values; + if (attr->isComplexAttr()) { LibertyAttrValueSeq *attr_values = attr->values(); if (attr_values->size() == 1) { LibertyAttrValue *value = (*attr_values)[0]; if (value->isString()) { - values = new FloatSeq; - parseStringFloatList(value->stringValue(), scale, values, attr); + values = parseStringFloatList(value->stringValue(), scale, attr); } else if (value->isFloat()) { - values = new FloatSeq; - values->push_back(value->floatValue()); + values.push_back(value->floatValue()); } else - libWarn(1276, attr, "%s is missing values.", attr->name()); + libWarn(1276, attr, "%s is missing values.", attr->name().c_str()); } else - libWarn(1277, attr, "%s has more than one string.", attr->name()); + libWarn(1277, attr, "%s has more than one string.", attr->name().c_str()); } else { LibertyAttrValue *value = attr->firstValue(); if (value->isString()) { - values = new FloatSeq; - parseStringFloatList(value->stringValue(), scale, values, attr); + values = parseStringFloatList(value->stringValue(), scale, attr); } else - libWarn(1278, attr, "%s is missing values.", attr->name()); + libWarn(1278, attr, "%s is missing values.", attr->name().c_str()); } return values; } @@ -5170,26 +5167,26 @@ LibertyReader::getAttrBool(LibertyAttr *attr, bool &exists) { exists = false; - if (attr->isSimple()) { + if (attr->isSimpleAttr()) { LibertyAttrValue *val = attr->firstValue(); if (val->isString()) { - const char *str = val->stringValue(); - if (stringEqual(str, "true")) { + const std::string &str = val->stringValue(); + if (stringEqual(str.c_str(), "true")) { value = true; exists = true; } - else if (stringEqual(str, "false")) { + else if (stringEqual(str.c_str(), "false")) { value = false; exists = true; } else - libWarn(1279, attr, "%s attribute is not boolean.", attr->name()); + libWarn(1279, attr, "%s attribute is not boolean.", attr->name().c_str()); } else - libWarn(1280, attr, "%s attribute is not boolean.", attr->name()); + libWarn(1280, attr, "%s attribute is not boolean.", attr->name().c_str()); } else - libWarn(1281, attr, "%s is not a simple attribute.", attr->name()); + libWarn(1281, attr, "%s is not a simple attribute.", attr->name().c_str()); } // Read L/H/X string attribute values as bool. @@ -5206,7 +5203,7 @@ LibertyReader::getAttrLogicValue(LibertyAttr *attr) return LogicValue::unknown; else libWarn(1282, attr, "attribute %s value %s not recognized.", - attr->name(), str); + attr->name().c_str(), str); // fall thru } return LogicValue::unknown; @@ -5248,17 +5245,11 @@ LibertyReader::visitVariable(LibertyVariable *var) { if (var_map_ == nullptr) var_map_ = new LibertyVariableMap; - const char *var_name = var->variable(); - string key; + const string &var_name = var->variable(); float value; bool exists; findKeyValue(var_map_, var_name, value, exists); - if (exists) { - // Duplicate variable name. - (*var_map_)[key] = var->value(); - } - else - (*var_map_)[var_name] = var->value(); + (*var_map_)[var_name] = var->value(); } void @@ -5337,17 +5328,11 @@ void LibertyReader::beginInternalPower(LibertyGroup *group) { if (port_group_) { - internal_power_ = makeInternalPowerGroup(group->line()); + internal_power_ = new InternalPowerGroup(group->line()); port_group_->addInternalPowerGroup(internal_power_); } } -InternalPowerGroup * -LibertyReader::makeInternalPowerGroup(int line) -{ - return new InternalPowerGroup(line); -} - void LibertyReader::endInternalPower(LibertyGroup *) { @@ -5378,7 +5363,7 @@ LibertyReader::endRiseFallPower(LibertyGroup *) if (table_) { TableModel *table_model = new TableModel(table_, tbl_template_, scale_factor_type_, rf_); - internal_power_->setModel(rf_, new InternalPowerModel(table_model)); + internal_power_->setModel(rf_, std::make_shared(table_model)); } endTableModel(); } @@ -5390,7 +5375,7 @@ LibertyReader::endPower(LibertyGroup *) TableModel *table_model = new TableModel(table_, tbl_template_, scale_factor_type_, rf_); // Share the model for rise/fall. - InternalPowerModel *power_model = new InternalPowerModel(table_model); + auto power_model = std::make_shared(table_model); internal_power_->setModel(RiseFall::rise(), power_model); internal_power_->setModel(RiseFall::fall(), power_model); } @@ -5472,7 +5457,7 @@ LibertyReader::beginOcvDerate(LibertyGroup *group) { const char *name = group->firstName(); if (name) - ocv_derate_ = new OcvDerate(stringCopy(name)); + ocv_derate_ = library_->makeOcvDerate(name); else libWarn(1285, group, "ocv_derate missing name."); } @@ -5480,10 +5465,6 @@ LibertyReader::beginOcvDerate(LibertyGroup *group) void LibertyReader::endOcvDerate(LibertyGroup *) { - if (cell_) - library_->addOcvDerate(ocv_derate_); - else if (library_) - library_->addOcvDerate(ocv_derate_); ocv_derate_ = nullptr; } @@ -5779,6 +5760,7 @@ PortGroup::~PortGroup() { deleteContents(timings_); delete ports_; + deleteContents(internal_power_groups_); } void @@ -6074,13 +6056,29 @@ TimingGroup::setOutputWaveforms(const RiseFall *rf, //////////////////////////////////////////////////////////////// InternalPowerGroup::InternalPowerGroup(int line) : - InternalPowerAttrs(), - RelatedPortGroup(line) + RelatedPortGroup(line), + when_(), + models_{} { } -InternalPowerGroup::~InternalPowerGroup() +void +InternalPowerGroup::setWhen(std::shared_ptr when) { + when_ = std::move(when); +} + +void +InternalPowerGroup::setModel(const RiseFall *rf, + std::shared_ptr model) +{ + models_[rf->index()] = std::move(model); +} + +void +InternalPowerGroup::setRelatedPgPin(std::string related_pg_pin) +{ + related_pg_pin_ = std::move(related_pg_pin); } //////////////////////////////////////////////////////////////// @@ -6094,6 +6092,8 @@ LeakagePowerGroup::LeakagePowerGroup(int line) : void LeakagePowerGroup::setRelatedPgPin(std::string pin_name) +<<<<<<< +======= { related_pg_pin_ = std::move(pin_name); } @@ -6104,6 +6104,23 @@ LeakagePowerGroup::setWhen(FuncExpr *when) when_ = when; } +void +LeakagePowerGroup::setPower(float power) +>>>>>>> +{ +<<<<<<< + related_pg_pin_ = std::move(pin_name); +======= + power_ = power; +>>>>>>> +} + +void +LeakagePowerGroup::setWhen(FuncExpr *when) +{ + when_ = when; +} + void LeakagePowerGroup::setPower(float power) { @@ -6258,7 +6275,7 @@ PortNameBitIterator::findRangeBusNameNext() OutputWaveform::OutputWaveform(float slew, float cap, - Table1 *currents, + Table *currents, float reference_time) : slew_(slew), cap_(cap), @@ -6272,10 +6289,10 @@ OutputWaveform::~OutputWaveform() delete currents_; } -Table1 * +Table * OutputWaveform::stealCurrents() { - Table1 *currents = currents_; + Table *currents = currents_; currents_ = nullptr; return currents; } diff --git a/liberty/LibertyReaderPvt.hh b/liberty/LibertyReaderPvt.hh index 26c74129..9016fc0a 100644 --- a/liberty/LibertyReaderPvt.hh +++ b/liberty/LibertyReaderPvt.hh @@ -25,8 +25,9 @@ #pragma once #include +#include #include -#include +#include #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; -using LibraryGroupMap = std::map; +using LibraryAttrMap = std::unordered_map; +using LibraryGroupMap = std::unordered_map; using PortGroupSeq = std::vector; using SequentialGroupSeq = std::vector; using LibertyFuncSeq = std::vector; @@ -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 &when() const { return when_; } + void setWhen(std::shared_ptr when); + void setModel(const RiseFall *rf, + std::shared_ptr model); + InternalPowerModels &models() { return models_; } + +private: + std::string related_pg_pin_; + std::shared_ptr 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_; }; diff --git a/liberty/LibertyWriter.cc b/liberty/LibertyWriter.cc index 4afa66f0..6c4b757f 100644 --- a/liberty/LibertyWriter.cc +++ b/liberty/LibertyWriter.cc @@ -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(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"); } diff --git a/liberty/Sequential.cc b/liberty/Sequential.cc index a89ae99b..782a22dc 100644 --- a/liberty/Sequential.cc +++ b/liberty/Sequential.cc @@ -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_; } //////////////////////////////////////////////////////////////// diff --git a/liberty/TableModel.cc b/liberty/TableModel.cc index 28741630..27512dc5 100644 --- a/liberty/TableModel.cc +++ b/liberty/TableModel.cc @@ -45,7 +45,9 @@ size_t findValueIndex(float value, const FloatSeq *values); static void -deleteSigmaModels(TableModel *models[EarlyLate::index_count]); +sigmaModelsMvOwner(TableModel *models[EarlyLate::index_count], + std::array, + EarlyLate::index_count> &out); static string reportPvt(const LibertyCell *cell, const Pvt *pvt, @@ -72,35 +74,29 @@ GateTableModel::GateTableModel(LibertyCell *cell, receiver_model_(receiver_model), output_waveforms_(output_waveforms) { - for (auto el_index : EarlyLate::rangeIndex()) { - slew_sigma_models_[el_index] = slew_sigma_models - ? slew_sigma_models[el_index] - : nullptr; - delay_sigma_models_[el_index] = delay_sigma_models - ? delay_sigma_models[el_index] - : nullptr; - } + sigmaModelsMvOwner(delay_sigma_models, delay_sigma_models_); + sigmaModelsMvOwner(slew_sigma_models, slew_sigma_models_); } -GateTableModel::~GateTableModel() -{ - delete delay_model_; - delete slew_model_; - delete output_waveforms_; - deleteSigmaModels(slew_sigma_models_); - deleteSigmaModels(delay_sigma_models_); -} +GateTableModel::~GateTableModel() = default; static void -deleteSigmaModels(TableModel *models[EarlyLate::index_count]) +sigmaModelsMvOwner(TableModel *models[EarlyLate::index_count], + std::array, + EarlyLate::index_count> &out) { - TableModel *early_model = models[EarlyLate::earlyIndex()]; - TableModel *late_model = models[EarlyLate::lateIndex()]; - if (early_model == late_model) - delete early_model; - else { - delete early_model; - delete late_model; + TableModel *early_model = models ? models[EarlyLate::earlyIndex()] : nullptr; + TableModel *late_model = models ? models[EarlyLate::lateIndex()] : nullptr; + if (early_model) { + out[EarlyLate::earlyIndex()].reset(early_model); + if (late_model && late_model != early_model) { + out[EarlyLate::lateIndex()].reset(late_model); + } else if (late_model == early_model) { + out[EarlyLate::lateIndex()] = + std::make_unique(*out[EarlyLate::earlyIndex()]); + } + } else if (late_model) { + out[EarlyLate::lateIndex()].reset(late_model); } } @@ -122,23 +118,23 @@ GateTableModel::gateDelay(const Pvt *pvt, ArcDelay &gate_delay, Slew &drvr_slew) const { - float delay = findValue(pvt, delay_model_, in_slew, load_cap, 0.0); + float delay = findValue(pvt, delay_model_.get(), in_slew, load_cap, 0.0); float sigma_early = 0.0; float sigma_late = 0.0; if (pocv_enabled && delay_sigma_models_[EarlyLate::earlyIndex()]) - sigma_early = findValue(pvt, delay_sigma_models_[EarlyLate::earlyIndex()], + sigma_early = findValue(pvt, delay_sigma_models_[EarlyLate::earlyIndex()].get(), in_slew, load_cap, 0.0); if (pocv_enabled && delay_sigma_models_[EarlyLate::lateIndex()]) - sigma_late = findValue(pvt, delay_sigma_models_[EarlyLate::lateIndex()], + sigma_late = findValue(pvt, delay_sigma_models_[EarlyLate::lateIndex()].get(), in_slew, load_cap, 0.0); gate_delay = makeDelay(delay, sigma_early, sigma_late); - float slew = findValue(pvt, slew_model_, in_slew, load_cap, 0.0); + float slew = findValue(pvt, slew_model_.get(), in_slew, load_cap, 0.0); if (pocv_enabled && slew_sigma_models_[EarlyLate::earlyIndex()]) - sigma_early = findValue(pvt, slew_sigma_models_[EarlyLate::earlyIndex()], + sigma_early = findValue(pvt, slew_sigma_models_[EarlyLate::earlyIndex()].get(), in_slew, load_cap, 0.0); if (pocv_enabled && slew_sigma_models_[EarlyLate::lateIndex()]) - sigma_late = findValue(pvt, slew_sigma_models_[EarlyLate::lateIndex()], + sigma_late = findValue(pvt, slew_sigma_models_[EarlyLate::lateIndex()].get(), in_slew, load_cap, 0.0); // Clip negative slews to zero. if (slew < 0.0) @@ -166,28 +162,28 @@ GateTableModel::reportGateDelay(const Pvt *pvt, int digits) const { string result = reportPvt(cell_, pvt, digits); - result += reportTableLookup("Delay", pvt, delay_model_, in_slew, + result += reportTableLookup("Delay", pvt, delay_model_.get(), in_slew, load_cap, 0.0, digits); if (pocv_enabled && delay_sigma_models_[EarlyLate::earlyIndex()]) result += reportTableLookup("Delay sigma(early)", pvt, - delay_sigma_models_[EarlyLate::earlyIndex()], + delay_sigma_models_[EarlyLate::earlyIndex()].get(), in_slew, load_cap, 0.0, digits); if (pocv_enabled && delay_sigma_models_[EarlyLate::lateIndex()]) result += reportTableLookup("Delay sigma(late)", pvt, - delay_sigma_models_[EarlyLate::lateIndex()], + delay_sigma_models_[EarlyLate::lateIndex()].get(), in_slew, load_cap, 0.0, digits); result += '\n'; - result += reportTableLookup("Slew", pvt, slew_model_, in_slew, + result += reportTableLookup("Slew", pvt, slew_model_.get(), in_slew, load_cap, 9.0, digits); if (pocv_enabled && slew_sigma_models_[EarlyLate::earlyIndex()]) result += reportTableLookup("Slew sigma(early)", pvt, - slew_sigma_models_[EarlyLate::earlyIndex()], + slew_sigma_models_[EarlyLate::earlyIndex()].get(), in_slew, load_cap, 0.0, digits); if (pocv_enabled && slew_sigma_models_[EarlyLate::lateIndex()]) result += reportTableLookup("Slew sigma(late)", pvt, - slew_sigma_models_[EarlyLate::lateIndex()], + slew_sigma_models_[EarlyLate::lateIndex()].get(), in_slew, load_cap, 0.0, digits); - float drvr_slew = findValue(pvt, slew_model_, in_slew, load_cap, 0.0); + float drvr_slew = findValue(pvt, slew_model_.get(), in_slew, load_cap, 0.0); if (drvr_slew < 0.0) result += "Negative slew clipped to 0.0\n"; return result; @@ -286,29 +282,46 @@ GateTableModel::driveResistance(const Pvt *pvt) const return slew / cap; } +const TableModel * +GateTableModel::delaySigmaModel(const EarlyLate *el) const +{ + return delay_sigma_models_[el->index()].get(); +} + +const TableModel * +GateTableModel::slewSigmaModel(const EarlyLate *el) const +{ + return slew_sigma_models_[el->index()].get(); +} + void GateTableModel::maxCapSlew(float in_slew, const Pvt *pvt, float &slew, float &cap) const { + if (!slew_model_) { + cap = 1.0; + slew = 0.0; + return; + } const TableAxis *axis1 = slew_model_->axis1(); const TableAxis *axis2 = slew_model_->axis2(); const TableAxis *axis3 = slew_model_->axis3(); if (axis1 && axis1->variable() == TableAxisVariable::total_output_net_capacitance) { cap = axis1->axisValue(axis1->size() - 1); - slew = findValue(pvt, slew_model_, in_slew, cap, 0.0); + slew = findValue(pvt, slew_model_.get(), in_slew, cap, 0.0); } else if (axis2 && axis2->variable()==TableAxisVariable::total_output_net_capacitance) { cap = axis2->axisValue(axis2->size() - 1); - slew = findValue(pvt, slew_model_, in_slew, cap, 0.0); + slew = findValue(pvt, slew_model_.get(), in_slew, cap, 0.0); } else if (axis3 && axis3->variable()==TableAxisVariable::total_output_net_capacitance) { cap = axis3->axisValue(axis3->size() - 1); - slew = findValue(pvt, slew_model_, in_slew, cap, 0.0); + slew = findValue(pvt, slew_model_.get(), in_slew, cap, 0.0); } else { // Table not dependent on capacitance. @@ -368,21 +381,17 @@ GateTableModel::checkAxis(const TableAxis *axis) //////////////////////////////////////////////////////////////// -ReceiverModel::~ReceiverModel() -{ - for (TableModel *model : capacitance_models_) - delete model; -} +ReceiverModel::~ReceiverModel() = default; void -ReceiverModel::setCapacitanceModel(TableModel *table_model, +ReceiverModel::setCapacitanceModel(TableModel table_model, size_t segment, const RiseFall *rf) { if ((segment + 1) * RiseFall::index_count > capacitance_models_.size()) capacitance_models_.resize((segment + 1) * RiseFall::index_count); size_t idx = segment * RiseFall::index_count + rf->index(); - capacitance_models_[idx] = table_model; + capacitance_models_[idx] = std::move(table_model); } bool @@ -410,20 +419,22 @@ CheckTableModel::CheckTableModel(LibertyCell *cell, CheckTimingModel(cell), model_(model) { - for (auto el_index : EarlyLate::rangeIndex()) - sigma_models_[el_index] = sigma_models ? sigma_models[el_index] : nullptr; + sigmaModelsMvOwner(sigma_models, sigma_models_); } -CheckTableModel::~CheckTableModel() -{ - delete model_; - deleteSigmaModels(sigma_models_); -} +CheckTableModel::~CheckTableModel() = default; void CheckTableModel::setIsScaled(bool is_scaled) { - model_->setIsScaled(is_scaled); + if (model_) + model_->setIsScaled(is_scaled); +} + +const TableModel * +CheckTableModel::sigmaModel(const EarlyLate *el) const +{ + return sigma_models_[el->index()].get(); } ArcDelay @@ -434,14 +445,14 @@ CheckTableModel::checkDelay(const Pvt *pvt, bool pocv_enabled) const { if (model_) { - float mean = findValue(pvt, model_, from_slew, to_slew, related_out_cap); + float mean = findValue(pvt, model_.get(), from_slew, to_slew, related_out_cap); float sigma_early = 0.0; float sigma_late = 0.0; if (pocv_enabled && sigma_models_[EarlyLate::earlyIndex()]) - sigma_early = findValue(pvt, sigma_models_[EarlyLate::earlyIndex()], + sigma_early = findValue(pvt, sigma_models_[EarlyLate::earlyIndex()].get(), from_slew, to_slew, related_out_cap); if (pocv_enabled && sigma_models_[EarlyLate::lateIndex()]) - sigma_late = findValue(pvt, sigma_models_[EarlyLate::lateIndex()], + sigma_late = findValue(pvt, sigma_models_[EarlyLate::lateIndex()].get(), from_slew, to_slew, related_out_cap); return makeDelay(mean, sigma_early, sigma_late); } @@ -475,17 +486,17 @@ CheckTableModel::reportCheckDelay(const Pvt *pvt, bool pocv_enabled, int digits) const { - string result = reportTableDelay("Check", pvt, model_, + string result = reportTableDelay("Check", pvt, model_.get(), from_slew, from_slew_annotation, to_slew, related_out_cap, digits); if (pocv_enabled && sigma_models_[EarlyLate::earlyIndex()]) result += reportTableDelay("Check sigma early", pvt, - sigma_models_[EarlyLate::earlyIndex()], + sigma_models_[EarlyLate::earlyIndex()].get(), from_slew, from_slew_annotation, to_slew, related_out_cap, digits); if (pocv_enabled && sigma_models_[EarlyLate::lateIndex()]) result += reportTableDelay("Check sigma late", pvt, - sigma_models_[EarlyLate::lateIndex()], + sigma_models_[EarlyLate::lateIndex()].get(), from_slew, from_slew_annotation, to_slew, related_out_cap, digits); return result; @@ -602,6 +613,15 @@ CheckTableModel::checkAxis(const TableAxis *axis) //////////////////////////////////////////////////////////////// +TableModel::TableModel() : + table_(nullptr), + tbl_template_(nullptr), + scale_factor_type_(0), + rf_index_(0), + is_scaled_(false) +{ +} + TableModel::TableModel(TablePtr table, TableTemplate *tbl_template, ScaleFactorType scale_factor_type, @@ -620,6 +640,12 @@ TableModel::order() const return table_->order(); } +ScaleFactorType +TableModel::scaleFactorType() const +{ + return static_cast(scale_factor_type_); +} + void TableModel::setScaleFactorType(ScaleFactorType type) { @@ -751,283 +777,181 @@ TableModel::reportPvtScaleFactor(const LibertyCell *cell, //////////////////////////////////////////////////////////////// -Table0::Table0(float value) : - Table(), +void +Table::clear() +{ + if (order_ == 1) + values1_.clear(); + else if (order_ == 2 || order_ == 3) + values_table_.clear(); +} + +FloatSeq * +Table::values() const +{ + return (order_ == 1) ? const_cast(&values1_) : nullptr; +} + +FloatTable * +Table::values3() +{ + return (order_ >= 2) ? &values_table_ : nullptr; +} + +const FloatTable * +Table::values3() const +{ + return (order_ >= 2) ? &values_table_ : nullptr; +} + +Table::Table() : + order_(0), + value_(0.0) +{ +} + +Table::Table(float value) : + order_(0), value_(value) { } -float -Table0::value(size_t, - size_t, - size_t) const +Table::Table(FloatSeq *values, + TableAxisPtr axis1) : + order_(1), + value_(0.0), + values1_(std::move(*values)), + axis1_(axis1) { - return value_; + delete values; } -float -Table0::findValue(float, - float, - float) const -{ - return value_; -} - -string -Table0::reportValue(const char *result_name, - const LibertyCell *, - const Pvt *, - float value1, - const char *comment1, - float value2, - float value3, - const Unit *table_unit, - int digits) const -{ - string result = result_name; - result += " constant = "; - result += table_unit->asString(findValue(value1, value2, value3), digits); - if (comment1) - result += comment1; - result += '\n'; - return result; -} - -void -Table0::report(const Units *units, - Report *report) const -{ - int digits = 4; - const Unit *table_unit = units->timeUnit(); - report->reportLine("%s", table_unit->asString(value_, digits)); -} - -//////////////////////////////////////////////////////////////// - -Table1::Table1() : - Table(), - values_(nullptr), - axis1_(nullptr) -{ -} - -Table1::Table1(FloatSeq *values, - TableAxisPtr axis1) : - Table(), - values_(values), +Table::Table(FloatSeq &&values, + TableAxisPtr axis1) : + order_(1), + value_(0.0), + values1_(std::move(values)), axis1_(axis1) { } -Table1::Table1(Table1 &&table) : - Table(), - values_(table.values_), - axis1_(table.axis1_) -{ - table.values_ = nullptr; - table.axis1_ = nullptr; -} - -Table1::Table1(const Table1 &table) : - Table(), - values_(new FloatSeq(*table.values_)), - axis1_(table.axis1_) -{ -} - -Table1::~Table1() -{ - delete values_; -} - -Table1 & -Table1::operator=(Table1 &&table) -{ - values_ = table.values_; - axis1_ = table.axis1_; - table.values_ = nullptr; - table.axis1_ = nullptr; - return *this; -} - -float -Table1::value(size_t axis_index1, - size_t, - size_t) const -{ - return value(axis_index1); -} - -float -Table1::value(size_t axis_index1) const -{ - return (*values_)[axis_index1]; -} - -float -Table1::findValue(float axis_value1, - float, - float) const -{ - return findValue(axis_value1); -} - -float -Table1::findValue(float axis_value1) const -{ - if (axis1_->size() == 1) - return this->value(axis_value1); - else { - size_t axis_index1 = axis1_->findAxisIndex(axis_value1); - double x1 = axis_value1; - double x1l = axis1_->axisValue(axis_index1); - double x1u = axis1_->axisValue(axis_index1 + 1); - double y1 = this->value(axis_index1); - double y2 = this->value(axis_index1 + 1); - double dx1 = (x1 - x1l) / (x1u - x1l); - return (1 - dx1) * y1 + dx1 * y2; - } -} - -float -Table1::findValueClip(float axis_value1) const -{ - if (axis1_->size() == 1) - return this->value(axis_value1); - else { - size_t axis_index1 = axis1_->findAxisIndex(axis_value1); - double x1 = axis_value1; - double x1l = axis1_->axisValue(axis_index1); - double x1u = axis1_->axisValue(axis_index1 + 1); - if (x1 < x1l) - return 0.0; - else if (x1 > x1u) - return this->value(axis1_->size() - 1); - else { - double y1 = this->value(axis_index1); - double y2 = this->value(axis_index1 + 1); - double dx1 = (x1 - x1l) / (x1u - x1l); - return (1 - dx1) * y1 + dx1 * y2; - } - } -} - -string -Table1::reportValue(const char *result_name, - const LibertyCell *cell, - const Pvt *, - float value1, - const char *comment1, - float value2, - float value3, - const Unit *table_unit, - int digits) const -{ - const Units *units = cell->libertyLibrary()->units(); - const Unit *unit1 = axis1_->unit(units); - string result = "Table is indexed by\n "; - result += axis1_->variableString(); - result += " = "; - result += unit1->asString(value1, digits); - if (comment1) - result += comment1; - result += '\n'; - - if (axis1_->size() != 1) { - size_t index1 = axis1_->findAxisIndex(value1); - result += " "; - result += unit1->asString(axis1_->axisValue(index1), digits); - result += " "; - result += unit1->asString(axis1_->axisValue(index1 + 1), digits); - result += '\n'; - - result += " --------------------\n"; - - result += "| "; - result += table_unit->asString(value(index1), digits); - result += " "; - result += table_unit->asString(value(index1 + 1), - digits); - result += '\n'; - } - - result += result_name; - result += " = "; - result += table_unit->asString(findValue(value1, value2, value3), digits); - result += '\n'; - return result; -} - -void -Table1::report(const Units *units, - Report *report) const -{ - int digits = 4; - const Unit *unit1 = axis1_->unit(units); - const Unit *table_unit = units->timeUnit(); - report->reportLine("%s", tableVariableString(axis1_->variable())); - report->reportLine("------------------------------"); - string line; - for (size_t index1 = 0; index1 < axis1_->size(); index1++) { - line += unit1->asString(axis1_->axisValue(index1), digits); - line += " "; - } - report->reportLineString(line); - - line.clear(); - for (size_t index1 = 0; index1 < axis1_->size(); index1++) { - line += table_unit->asString(value(index1), digits); - line += " "; - } - report->reportLineString(line); -} - -//////////////////////////////////////////////////////////////// - -Table2::Table2(FloatTable *values, - TableAxisPtr axis1, - TableAxisPtr axis2) : - Table(), - values_(values), +Table::Table(FloatTable &&values, + TableAxisPtr axis1, + TableAxisPtr axis2) : + order_(2), + value_(0.0), + values_table_(std::move(values)), axis1_(axis1), axis2_(axis2) { } -Table2::~Table2() +Table::Table(FloatTable &&values, + TableAxisPtr axis1, + TableAxisPtr axis2, + TableAxisPtr axis3) : + order_(3), + value_(0.0), + values_table_(std::move(values)), + axis1_(axis1), + axis2_(axis2), + axis3_(axis3) +{ +} + +Table::Table(Table &&table) : + order_(table.order_), + value_(table.value_), + values1_(std::move(table.values1_)), + values_table_(std::move(table.values_table_)), + axis1_(table.axis1_), + axis2_(table.axis2_), + axis3_(table.axis3_) +{ +} + +Table::Table(const Table &table) : + order_(table.order_), + value_(table.value_), + values1_(table.values1_), + values_table_(table.values_table_), + axis1_(table.axis1_), + axis2_(table.axis2_), + axis3_(table.axis3_) +{ +} + +Table & +Table::operator=(Table &&table) +{ + if (this != &table) { + order_ = table.order_; + value_ = table.value_; + values1_ = std::move(table.values1_); + values_table_ = std::move(table.values_table_); + axis1_ = table.axis1_; + axis2_ = table.axis2_; + axis3_ = table.axis3_; + } + return *this; +} + +void +Table::setScaleFactorType(ScaleFactorType) +{ +} + +void +Table::setIsScaled(bool) { - deleteContents(*values_); - delete values_; } float -Table2::value(size_t axis_index1, - size_t axis_index2, - size_t) const +Table::value(size_t axis_idx1, + size_t axis_idx2, + size_t axis_idx3) const { - return value(axis_index1, axis_index2); + if (order_ == 0) + return value_; + if (order_ == 1) + return values1_[axis_idx1]; + if (order_ == 2) + return values_table_[axis_idx1][axis_idx2]; + // order_ == 3 + size_t row = axis_idx1 * axis2_->size() + axis_idx2; + return values_table_[row][axis_idx3]; } float -Table2::value(size_t axis_index1, - size_t axis_index2) const +Table::value(size_t index1) const { - FloatSeq *row = (*values_)[axis_index1]; - return (*row)[axis_index2]; + if (order_ != 1 || values1_.empty()) + return value_; + return values1_[index1]; } -// Bilinear Interpolation. float -Table2::findValue(float axis_value1, - float axis_value2, - float) const +Table::value(size_t axis_index1, + size_t axis_index2) const { - size_t size1 = axis1_->size(); - size_t size2 = axis2_->size(); - if (size1 == 1) { - if (size2 == 1) - return value(0, 0); - else { + return values_table_[axis_index1][axis_index2]; +} + +float +Table::findValue(float axis_value1, + float axis_value2, + float axis_value3) const +{ + if (order_ == 0) + return value_; + if (order_ == 1) + return findValue(axis_value1); + if (order_ == 2) { + size_t size1 = axis1_->size(); + size_t size2 = axis2_->size(); + if (size1 == 1) { + if (size2 == 1) + return value(0, 0); size_t axis_index2 = axis2_->findAxisIndex(axis_value2); double x2 = axis_value2; double y00 = value(0, axis_index2); @@ -1035,26 +959,18 @@ Table2::findValue(float axis_value1, double x2u = axis2_->axisValue(axis_index2 + 1); double dx2 = (x2 - x2l) / (x2u - x2l); double y01 = value(0, axis_index2 + 1); - double tbl_value - = (1 - dx2) * y00 - + dx2 * y01; - return tbl_value; + return (1 - dx2) * y00 + dx2 * y01; + } + if (size2 == 1) { + size_t axis_index1 = axis1_->findAxisIndex(axis_value1); + double x1 = axis_value1; + double y00 = value(axis_index1, 0); + double x1l = axis1_->axisValue(axis_index1); + double x1u = axis1_->axisValue(axis_index1 + 1); + double dx1 = (x1 - x1l) / (x1u - x1l); + double y10 = value(axis_index1 + 1, 0); + return (1 - dx1) * y00 + dx1 * y10; } - } - else if (size2 == 1) { - size_t axis_index1 = axis1_->findAxisIndex(axis_value1); - double x1 = axis_value1; - double y00 = value(axis_index1, 0); - double x1l = axis1_->axisValue(axis_index1); - double x1u = axis1_->axisValue(axis_index1 + 1); - double dx1 = (x1 - x1l) / (x1u - x1l); - double y10 = value(axis_index1 + 1, 0); - double tbl_value - = (1 - dx1) * y00 - + dx1 * y10; - return tbl_value; - } - else { size_t axis_index1 = axis1_->findAxisIndex(axis_value1); size_t axis_index2 = axis2_->findAxisIndex(axis_value2); double x1 = axis_value1; @@ -1069,136 +985,12 @@ Table2::findValue(float axis_value1, double x2u = axis2_->axisValue(axis_index2 + 1); double dx2 = (x2 - x2l) / (x2u - x2l); double y01 = value(axis_index1, axis_index2 + 1); - double tbl_value - = (1 - dx1) * (1 - dx2) * y00 - + dx1 * (1 - dx2) * y10 - + dx1 * dx2 * y11 - + (1 - dx1) * dx2 * y01; - return tbl_value; + return (1 - dx1) * (1 - dx2) * y00 + + dx1 * (1 - dx2) * y10 + + dx1 * dx2 * y11 + + (1 - dx1) * dx2 * y01; } -} - -string -Table2::reportValue(const char *result_name, - const LibertyCell *cell, - const Pvt *, - float value1, - const char *comment1, - float value2, - float value3, - const Unit *table_unit, - int digits) const -{ - const Units *units = cell->libertyLibrary()->units(); - const Unit *unit1 = axis1_->unit(units); - const Unit *unit2 = axis2_->unit(units); - string result = "------- "; - result += axis1_->variableString(), - result += " = "; - result += unit1->asString(value1, digits); - if (comment1) - result += comment1; - result += '\n'; - - result += "| "; - result += axis2_->variableString(); - result += " = "; - result += unit2->asString(value2, digits); - result += '\n'; - - size_t index1 = axis1_->findAxisIndex(value1); - size_t index2 = axis2_->findAxisIndex(value2); - result += "| "; - result += unit2->asString(axis2_->axisValue(index2), digits); - if (axis2_->size() != 1) { - result += " "; - result += unit2->asString(axis2_->axisValue(index2 + 1), digits); - } - result += '\n'; - - result += "v --------------------\n"; - result += unit1->asString(axis1_->axisValue(index1), digits); - result += " | "; - - result += table_unit->asString(value(index1, index2), digits); - if (axis2_->size() != 1) { - result += " "; - result += table_unit->asString(value(index1, index2 + 1), digits); - } - result += '\n'; - - if (axis1_->size() != 1) { - result += unit1->asString(axis1_->axisValue(index1 + 1), digits); - result += " | "; - result += table_unit->asString(value(index1 + 1, index2), digits); - if (axis2_->size() != 1) { - result += " "; - result +=table_unit->asString(value(index1 + 1, index2 + 1),digits); - } - } - result += '\n'; - - result += result_name; - result += " = "; - result += table_unit->asString(findValue(value1, value2, value3), digits); - result += '\n'; - return result; -} - -void -Table2::report(const Units *units, - Report *report) const -{ - int digits = 4; - const Unit *table_unit = units->timeUnit(); - const Unit *unit1 = axis1_->unit(units); - const Unit *unit2 = axis2_->unit(units); - report->reportLine("%s", tableVariableString(axis2_->variable())); - report->reportLine(" ------------------------------"); - string line = " "; - for (size_t index2 = 0; index2 < axis2_->size(); index2++) { - line += unit2->asString(axis2_->axisValue(index2), digits); - line += " "; - } - report->reportLineString(line); - - for (size_t index1 = 0; index1 < axis1_->size(); index1++) { - line = unit1->asString(axis1_->axisValue(index1), digits); - line += " |"; - for (size_t index2 = 0; index2 < axis2_->size(); index2++) { - line += table_unit->asString(value(index1, index2), digits); - line += " "; - } - report->reportLineString(line); - } -} - -//////////////////////////////////////////////////////////////// - -Table3::Table3(FloatTable *values, - TableAxisPtr axis1, - TableAxisPtr axis2, - TableAxisPtr axis3) : - Table2(values, axis1, axis2), - axis3_(axis3) -{ -} - -float -Table3::value(size_t axis_index1, - size_t axis_index2, - size_t axis_index3) const -{ - size_t row = axis_index1 * axis2_->size() + axis_index2; - return values_->operator[](row)->operator[](axis_index3); -} - -// Bilinear Interpolation. -float -Table3::findValue(float axis_value1, - float axis_value2, - float axis_value3) const -{ + // order_ == 3 - trilinear interpolation size_t axis_index1 = axis1_->findAxisIndex(axis_value1); size_t axis_index2 = axis2_->findAxisIndex(axis_value2); size_t axis_index3 = axis3_->findAxisIndex(axis_value3); @@ -1245,69 +1037,259 @@ Table3::findValue(float axis_value1, y001 = value(axis_index1, axis_index2, axis_index3 + 1); } - double tbl_value - = (1 - dx1) * (1 - dx2) * (1 - dx3) * y000 - + (1 - dx1) * (1 - dx2) * dx3 * y001 - + (1 - dx1) * dx2 * (1 - dx3) * y010 - + (1 - dx1) * dx2 * dx3 * y011 - + dx1 * (1 - dx2) * (1 - dx3) * y100 - + dx1 * (1 - dx2) * dx3 * y101 - + dx1 * dx2 * (1 - dx3) * y110 - + dx1 * dx2 * dx3 * y111; - return tbl_value; + return (1 - dx1) * (1 - dx2) * (1 - dx3) * y000 + + (1 - dx1) * (1 - dx2) * dx3 * y001 + + (1 - dx1) * dx2 * (1 - dx3) * y010 + + (1 - dx1) * dx2 * dx3 * y011 + + dx1 * (1 - dx2) * (1 - dx3) * y100 + + dx1 * (1 - dx2) * dx3 * y101 + + dx1 * dx2 * (1 - dx3) * y110 + + dx1 * dx2 * dx3 * y111; } -// Sample output. -// -// --------- input_net_transition = 0.00 -// | ---- total_output_net_capacitance = 0.20 -// | | related_out_total_output_net_capacitance = 0.10 -// | | 0.00 0.30 -// v | -------------------- -// 0.01 v / 0.23 0.25 -// 0.00 0.20 | 0.10 0.20 -// |/ 0.30 0.32 -// 0.40 | 0.20 0.30 -string -Table3::reportValue(const char *result_name, - const LibertyCell *cell, - const Pvt *, - float value1, - const char *comment1, - float value2, - float value3, - const Unit *table_unit, - int digits) const +void +Table::findValue(float axis_value1, + float &value, + bool &extrapolated) const +{ + if (axis1_->size() == 1) { + value = this->value(0); + extrapolated = false; + return; + } + size_t axis_index1 = axis1_->findAxisIndex(axis_value1); + double x1 = axis_value1; + double x1l = axis1_->axisValue(axis_index1); + double x1u = axis1_->axisValue(axis_index1 + 1); + double y1 = this->value(axis_index1); + double y2 = this->value(axis_index1 + 1); + double dx1 = (x1 - x1l) / (x1u - x1l); + value = (1 - dx1) * y1 + dx1 * y2; + extrapolated = (axis_value1 < x1l || axis_value1 > x1u); +} + +float +Table::findValue(float axis_value1) const +{ + if (axis1_->size() == 1) + return value(0); + size_t axis_index1 = axis1_->findAxisIndex(axis_value1); + double x1 = axis_value1; + double x1l = axis1_->axisValue(axis_index1); + double x1u = axis1_->axisValue(axis_index1 + 1); + double y1 = value(axis_index1); + double y2 = value(axis_index1 + 1); + double dx1 = (x1 - x1l) / (x1u - x1l); + return (1 - dx1) * y1 + dx1 * y2; +} + +float +Table::findValueClip(float axis_value1) const +{ + if (axis1_->size() == 1) + return value(0); + size_t axis_index1 = axis1_->findAxisIndex(axis_value1); + double x1 = axis_value1; + double x1l = axis1_->axisValue(axis_index1); + double x1u = axis1_->axisValue(axis_index1 + 1); + if (x1 < x1l) + return 0.0; + if (x1 > x1u) + return value(axis1_->size() - 1); + double y1 = value(axis_index1); + double y2 = value(axis_index1 + 1); + double dx1 = (x1 - x1l) / (x1u - x1l); + return (1 - dx1) * y1 + dx1 * y2; +} + +float +Table::findValue(const LibertyLibrary *, + const LibertyCell *, + const Pvt *, + float axis_value1, + float axis_value2, + float axis_value3) const +{ + return findValue(axis_value1, axis_value2, axis_value3); +} + +std::string +Table::reportValue(const char *result_name, + const LibertyCell *cell, + const Pvt *, + float value1, + const char *comment1, + float value2, + float value3, + const Unit *table_unit, + int digits) const +{ + switch (order_) { + case 0: + return reportValueOrder0(result_name, comment1, table_unit, digits); + case 1: + return reportValueOrder1(result_name, cell, value1, comment1, + value2, value3, table_unit, digits); + case 2: + return reportValueOrder2(result_name, cell, value1, comment1, + value2, value3, table_unit, digits); + case 3: + return reportValueOrder3(result_name, cell, value1, comment1, + value2, value3, table_unit, digits); + default: + return ""; + } +} + +std::string +Table::reportValueOrder0(const char *result_name, + const char *comment1, + const Unit *table_unit, + int digits) const +{ + string result = result_name; + result += " constant = "; + result += table_unit->asString(value_, digits); + if (comment1) + result += comment1; + result += '\n'; + return result; +} + +std::string +Table::reportValueOrder1(const char *result_name, + const LibertyCell *cell, + float value1, + const char *comment1, + float value2, + float value3, + const Unit *table_unit, + int digits) const { const Units *units = cell->libertyLibrary()->units(); const Unit *unit1 = axis1_->unit(units); - const Unit *unit2 = axis2_->unit(units); - const Unit *unit3 = axis3_->unit(units); - - string result = " --------- "; - result += axis1_->variableString(), + string result = "Table is indexed by\n "; + result += axis1_->variableString(); result += " = "; result += unit1->asString(value1, digits); if (comment1) result += comment1; result += '\n'; + if (axis1_->size() != 1) { + size_t index1 = axis1_->findAxisIndex(value1); + result += " "; + result += unit1->asString(axis1_->axisValue(index1), digits); + result += " "; + result += unit1->asString(axis1_->axisValue(index1 + 1), digits); + result += '\n'; + result += " --------------------\n"; + result += "| "; + result += table_unit->asString(value(index1), digits); + result += " "; + result += table_unit->asString(value(index1 + 1), digits); + result += '\n'; + } + result += result_name; + result += " = "; + result += table_unit->asString(findValue(value1, value2, value3), digits); + result += '\n'; + return result; +} - result += " | ---- "; - result += axis2_->variableString(), +std::string +Table::reportValueOrder2(const char *result_name, + const LibertyCell *cell, + float value1, + const char *comment1, + float value2, + float value3, + const Unit *table_unit, + int digits) const +{ + const Units *units = cell->libertyLibrary()->units(); + const Unit *unit1 = axis1_->unit(units); + const Unit *unit2 = axis2_->unit(units); + string result = "------- "; + result += axis1_->variableString(); + result += " = "; + result += unit1->asString(value1, digits); + if (comment1) + result += comment1; + result += '\n'; + result += "| "; + result += axis2_->variableString(); result += " = "; result += unit2->asString(value2, digits); result += '\n'; + size_t index1 = axis1_->findAxisIndex(value1); + size_t index2 = axis2_->findAxisIndex(value2); + result += "| "; + result += unit2->asString(axis2_->axisValue(index2), digits); + if (axis2_->size() != 1) { + result += " "; + result += unit2->asString(axis2_->axisValue(index2 + 1), digits); + } + result += '\n'; + result += "v --------------------\n"; + result += unit1->asString(axis1_->axisValue(index1), digits); + result += " | "; + result += table_unit->asString(value(index1, index2), digits); + if (axis2_->size() != 1) { + result += " "; + result += table_unit->asString(value(index1, index2 + 1), digits); + } + result += '\n'; + if (axis1_->size() != 1) { + result += unit1->asString(axis1_->axisValue(index1 + 1), digits); + result += " | "; + result += table_unit->asString(value(index1 + 1, index2), digits); + if (axis2_->size() != 1) { + result += " "; + result += table_unit->asString(value(index1 + 1, index2 + 1), digits); + } + } + result += '\n'; + result += result_name; + result += " = "; + result += table_unit->asString(findValue(value1, value2, value3), digits); + result += '\n'; + return result; +} +std::string +Table::reportValueOrder3(const char *result_name, + const LibertyCell *cell, + float value1, + const char *comment1, + float value2, + float value3, + const Unit *table_unit, + int digits) const +{ + const Units *units = cell->libertyLibrary()->units(); + const Unit *unit1 = axis1_->unit(units); + const Unit *unit2 = axis2_->unit(units); + const Unit *unit3 = axis3_->unit(units); + string result = " --------- "; + result += axis1_->variableString(); + result += " = "; + result += unit1->asString(value1, digits); + if (comment1) + result += comment1; + result += '\n'; + result += " | ---- "; + result += axis2_->variableString(); + result += " = "; + result += unit2->asString(value2, digits); + result += '\n'; result += " | | "; result += axis3_->variableString(); result += " = "; result += unit3->asString(value3, digits); result += '\n'; - size_t axis_index1 = axis1_->findAxisIndex(value1); size_t axis_index2 = axis2_->findAxisIndex(value2); size_t axis_index3 = axis3_->findAxisIndex(value3); - result += " | | "; result += unit3->asString(axis3_->axisValue(axis_index3), digits); if (axis3_->size() != 1) { @@ -1315,66 +1297,60 @@ Table3::reportValue(const char *result_name, result += unit3->asString(axis3_->axisValue(axis_index3 + 1), digits); } result += '\n'; - result += " v | --------------------\n"; - if (axis1_->size() != 1) { result += " "; - result += unit1->asString(axis1_->axisValue(axis_index1+1), digits); + result += unit1->asString(axis1_->axisValue(axis_index1 + 1), digits); result += " v / "; - result += table_unit->asString(value(axis_index1+1,axis_index2,axis_index3), - digits); + result += table_unit->asString(value(axis_index1 + 1, axis_index2, + axis_index3), digits); if (axis3_->size() != 1) { result += " "; - result += table_unit->asString(value(axis_index1+1,axis_index2,axis_index3+1), - digits); + result += table_unit->asString(value(axis_index1 + 1, axis_index2, + axis_index3 + 1), digits); } } else { - appendSpaces(result, digits+3); + appendSpaces(result, digits + 3); result += " v / "; } result += '\n'; - result += unit1->asString(axis1_->axisValue(axis_index1), digits); result += " "; result += unit2->asString(axis2_->axisValue(axis_index2), digits); result += " | "; - result += table_unit->asString(value(axis_index1, axis_index2, axis_index3), digits); + result += table_unit->asString(value(axis_index1, axis_index2, + axis_index3), digits); if (axis3_->size() != 1) { result += " "; - result += table_unit->asString(value(axis_index1, axis_index2, axis_index3+1), - digits); + result += table_unit->asString(value(axis_index1, axis_index2, + axis_index3 + 1), digits); } result += '\n'; - result += " |/ "; - if (axis1_->size() != 1 - && axis2_->size() != 1) { - result += table_unit->asString(value(axis_index1+1,axis_index2+1,axis_index3), - digits); + if (axis1_->size() != 1 && axis2_->size() != 1) { + result += table_unit->asString(value(axis_index1 + 1, axis_index2 + 1, + axis_index3), digits); if (axis3_->size() != 1) { result += " "; - result +=table_unit->asString(value(axis_index1+1,axis_index2+1,axis_index3+1), - digits); + result += table_unit->asString(value(axis_index1 + 1, axis_index2 + 1, + axis_index3 + 1), digits); } } result += '\n'; - result += " "; result += unit2->asString(axis2_->axisValue(axis_index2 + 1), digits); result += " | "; if (axis2_->size() != 1) { - result += table_unit->asString(value(axis_index1, axis_index2+1, axis_index3), - digits); + result += table_unit->asString(value(axis_index1, axis_index2 + 1, + axis_index3), digits); if (axis3_->size() != 1) { result += " "; - result +=table_unit->asString(value(axis_index1, axis_index2+1,axis_index3+1), - digits); + result += table_unit->asString(value(axis_index1, axis_index2 + 1, + axis_index3 + 1), digits); } } result += '\n'; - result += result_name; result += " = "; result += table_unit->asString(findValue(value1, value2, value3), digits); @@ -1382,6 +1358,83 @@ Table3::reportValue(const char *result_name, return result; } +void +Table::report(const Units *units, + Report *report) const +{ + int digits = 4; + const Unit *table_unit = units->timeUnit(); + if (order_ == 0) { + report->reportLine("%s", table_unit->asString(value_, digits)); + return; + } + if (order_ == 1) { + const Unit *unit1 = axis1_->unit(units); + report->reportLine("%s", tableVariableString(axis1_->variable())); + report->reportLine("------------------------------"); + string line; + for (size_t index1 = 0; index1 < axis1_->size(); index1++) { + line += unit1->asString(axis1_->axisValue(index1), digits); + line += " "; + } + report->reportLineString(line); + line.clear(); + for (size_t index1 = 0; index1 < axis1_->size(); index1++) { + line += table_unit->asString(value(index1), digits); + line += " "; + } + report->reportLineString(line); + return; + } + if (order_ == 2) { + const Unit *unit1 = axis1_->unit(units); + const Unit *unit2 = axis2_->unit(units); + report->reportLine("%s", tableVariableString(axis2_->variable())); + report->reportLine(" ------------------------------"); + string line = " "; + for (size_t index2 = 0; index2 < axis2_->size(); index2++) { + line += unit2->asString(axis2_->axisValue(index2), digits); + line += " "; + } + report->reportLineString(line); + for (size_t index1 = 0; index1 < axis1_->size(); index1++) { + line = unit1->asString(axis1_->axisValue(index1), digits); + line += " |"; + for (size_t index2 = 0; index2 < axis2_->size(); index2++) { + line += table_unit->asString(value(index1, index2), digits); + line += " "; + } + report->reportLineString(line); + } + return; + } + // order_ == 3 + const Unit *unit1 = axis1_->unit(units); + const Unit *unit2 = axis2_->unit(units); + const Unit *unit3 = axis3_->unit(units); + for (size_t axis_index1 = 0; axis_index1 < axis1_->size(); axis_index1++) { + report->reportLine("%s %s", tableVariableString(axis1_->variable()), + unit1->asString(axis1_->axisValue(axis_index1), digits)); + report->reportLine("%s", tableVariableString(axis3_->variable())); + report->reportLine(" ------------------------------"); + string line = " "; + for (size_t axis_index3 = 0; axis_index3 < axis3_->size(); axis_index3++) { + line += unit3->asString(axis3_->axisValue(axis_index3), digits); + line += " "; + } + report->reportLineString(line); + for (size_t axis_index2 = 0; axis_index2 < axis2_->size(); axis_index2++) { + line = unit2->asString(axis2_->axisValue(axis_index2), digits); + line += " |"; + for (size_t axis_index3 = 0; axis_index3 < axis3_->size(); axis_index3++) { + line += table_unit->asString(value(axis_index1, axis_index2, axis_index3), digits); + line += " "; + } + report->reportLineString(line); + } + } +} + static void appendSpaces(string &result, int count) @@ -1390,59 +1443,20 @@ appendSpaces(string &result, result += ' '; } -void -Table3::report(const Units *units, - Report *report) const -{ - int digits = 4; - const Unit *table_unit = units->timeUnit(); - const Unit *unit1 = axis1_->unit(units); - const Unit *unit2 = axis2_->unit(units); - const Unit *unit3 = axis3_->unit(units); - for (size_t axis_index1 = 0; axis_index1 < axis1_->size(); axis_index1++) { - report->reportLine("%s %s", tableVariableString(axis1_->variable()), - unit1->asString(axis1_->axisValue(axis_index1), digits)); - - report->reportLine("%s", tableVariableString(axis3_->variable())); - report->reportLine(" ------------------------------"); - string line = " "; - for (size_t axis_index3 = 0; axis_index3 < axis3_->size(); axis_index3++) { - line += unit3->asString(axis3_->axisValue(axis_index3), digits); - line += " "; - } - report->reportLineString(line); - - for (size_t axis_index2 = 0; axis_index2 < axis2_->size(); axis_index2++) { - line = unit2->asString(axis2_->axisValue(axis_index2),digits); - line += " |"; - for (size_t axis_index3 = 0; axis_index3 < axis3_->size(); axis_index3++) { - line += table_unit->asString(value(axis_index1, axis_index2, axis_index3),digits); - line += " "; - } - report->reportLineString(line); - } - } -} - //////////////////////////////////////////////////////////////// TableAxis::TableAxis(TableAxisVariable variable, - FloatSeq *values) : + FloatSeq &&values) : variable_(variable), - values_(values) + values_(std::move(values)) { } -TableAxis::~TableAxis() -{ - delete values_; -} - float TableAxis::min() const { - if (!values_->empty()) - return (*values_)[0]; + if (!values_.empty()) + return values_[0]; else return 0.0; } @@ -1450,9 +1464,9 @@ TableAxis::min() const float TableAxis::max() const { - size_t size = values_->size(); + size_t size = values_.size(); if (size > 0) - return (*values_)[values_->size() - 1]; + return values_[values_.size() - 1]; else return 0.0; } @@ -1460,16 +1474,16 @@ TableAxis::max() const bool TableAxis::inBounds(float value) const { - size_t size = values_->size(); + size_t size = values_.size(); return size > 1 - && value >= (*values_)[0] - && value <= (*values_)[size - 1]; + && value >= values_[0] + && value <= values_[size - 1]; } size_t TableAxis::findAxisIndex(float value) const { - return findValueIndex(value, values_); + return findValueIndex(value, &values_); } // Bisection search. @@ -1504,20 +1518,20 @@ TableAxis::findAxisIndex(float value, size_t &index, bool &exists) const { - size_t size = values_->size(); + size_t size = values_.size(); if (size != 0 - && value >= (*values_)[0] - && value <= (*values_)[size - 1]) { + && value >= values_[0] + && value <= values_[size - 1]) { int lower = -1; int upper = size; while (upper - lower > 1) { int mid = (upper + lower) >> 1; - if (value == (*values_)[mid]) { + if (value == values_[mid]) { index = mid; exists = true; return; } - if (value > (*values_)[mid]) + if (value > values_[mid]) lower = mid; else upper = mid; @@ -1529,22 +1543,22 @@ TableAxis::findAxisIndex(float value, size_t TableAxis::findAxisClosestIndex(float value) const { - size_t size = values_->size(); - if (size <= 1 || value <= (*values_)[0]) + size_t size = values_.size(); + if (size <= 1 || value <= values_[0]) return 0; - else if (value >= (*values_)[size - 1]) + else if (value >= values_[size - 1]) return size - 1; else { int lower = -1; int upper = size; while (upper - lower > 1) { int mid = (upper + lower) >> 1; - if (value >= (*values_)[mid]) + if (value >= values_[mid]) lower = mid; else upper = mid; } - if ((value - (*values_)[lower]) < ((*values_)[upper] - value)) + if ((value - values_[lower]) < (values_[upper] - value)) return lower; else return upper; @@ -1574,7 +1588,8 @@ static EnumNameMap table_axis_variable_map = {TableAxisVariable::constrained_pin_transition, "constrained_pin_transition"}, {TableAxisVariable::output_pin_transition, "output_pin_transition"}, {TableAxisVariable::connect_delay, "connect_delay"}, - {TableAxisVariable::related_out_total_output_net_capacitance, "related_out_total_output_net_capacitance"}, + {TableAxisVariable::related_out_total_output_net_capacitance, + "related_out_total_output_net_capacitance"}, {TableAxisVariable::time, "time"}, {TableAxisVariable::iv_output_voltage, "iv_output_voltage"}, {TableAxisVariable::input_noise_width, "input_noise_width"}, @@ -1638,22 +1653,21 @@ OutputWaveforms::OutputWaveforms(TableAxisPtr slew_axis, TableAxisPtr cap_axis, const RiseFall *rf, Table1Seq ¤t_waveforms, - Table1 *ref_times) : + Table ref_times) : slew_axis_(slew_axis), cap_axis_(cap_axis), rf_(rf), current_waveforms_(current_waveforms), - ref_times_(ref_times), + ref_times_(std::move(ref_times)), vdd_(0.0) { } OutputWaveforms::~OutputWaveforms() { - deleteContents(current_waveforms_);; + deleteContents(current_waveforms_); deleteContents(voltage_waveforms_); deleteContents(voltage_currents_); - delete ref_times_; } bool @@ -1697,13 +1711,13 @@ OutputWaveforms::findVoltages(size_t wave_index, { // Integrate current waveform to find voltage waveform. // i = C dv/dt - FloatSeq *volts = new FloatSeq; - Table1 *currents = current_waveforms_[wave_index]; + FloatSeq volts; + Table *currents = current_waveforms_[wave_index]; const TableAxis *time_axis = currents->axis1(); float prev_time = time_axis->axisValue(0); float prev_current = currents->value(0); float voltage = 0.0; - volts->push_back(voltage); + volts.push_back(voltage); bool always_rise = true; bool invert = (always_rise && rf_ == RiseFall::fall()); for (size_t i = 1; i < time_axis->size(); i++) { @@ -1711,24 +1725,24 @@ OutputWaveforms::findVoltages(size_t wave_index, float current = currents->value(i); float dv = (current + prev_current) / 2.0 * (time - prev_time) / cap; voltage += invert ? -dv : dv; - volts->push_back(voltage); + volts.push_back(voltage); prev_time = time; prev_current = current; } - (*volts)[volts->size() - 1] = vdd_; - Table1 *volt_table = new Table1(volts, currents->axis1ptr()); + volts[volts.size() - 1] = vdd_; + Table *volt_table = new Table(new FloatSeq(volts), currents->axis1ptr()); voltage_waveforms_[wave_index] = volt_table; // Make voltage -> current table. - FloatSeq *axis_volts = new FloatSeq(*volts); + FloatSeq axis_volts = volts; TableAxisPtr volt_axis = - make_shared(TableAxisVariable::input_voltage, axis_volts); + make_shared(TableAxisVariable::input_voltage, std::move(axis_volts)); FloatSeq *currents1 = new FloatSeq(*currents->values()); - Table1 *volt_currents = new Table1(currents1, volt_axis); + Table *volt_currents = new Table(currents1, volt_axis); voltage_currents_[wave_index] = volt_currents; } -Table1 +Table OutputWaveforms::currentWaveform(float slew, float cap) { @@ -1741,11 +1755,12 @@ OutputWaveforms::currentWaveform(float slew, times->push_back(time); currents->push_back(current); } - TableAxisPtr time_axis = make_shared(TableAxisVariable::time, times); - return Table1(currents, time_axis); + TableAxisPtr time_axis = make_shared(TableAxisVariable::time, std::move(*times)); + delete times; + return Table(currents, time_axis); } -const Table1 * +const Table * OutputWaveforms::currentWaveformRaw(float slew, float cap) { @@ -1834,7 +1849,7 @@ float OutputWaveforms::voltageTime2(float volt, size_t wave_index) { - const Table1 *voltage_waveform = voltage_waveforms_[wave_index]; + const Table *voltage_waveform = voltage_waveforms_[wave_index]; const FloatSeq *voltages = voltage_waveform->values(); size_t index1 = findValueIndex(volt, voltages); float volt_lo = (*voltages)[index1]; @@ -1870,10 +1885,10 @@ OutputWaveforms::waveformValue(float slew, size_t wave_index10 = (slew_index + 1) * cap_count + cap_index; size_t wave_index11 = (slew_index + 1) * cap_count + (cap_index + 1); - const Table1 *waveform00 = waveforms[wave_index00]; - const Table1 *waveform01 = waveforms[wave_index01]; - const Table1 *waveform10 = waveforms[wave_index10]; - const Table1 *waveform11 = waveforms[wave_index11]; + const Table *waveform00 = waveforms[wave_index00]; + const Table *waveform01 = waveforms[wave_index01]; + const Table *waveform10 = waveforms[wave_index10]; + const Table *waveform11 = waveforms[wave_index11]; // Interpolate waveform samples at voltage steps. size_t index1 = slew_index; @@ -1902,26 +1917,27 @@ OutputWaveforms::waveformValue(float slew, float OutputWaveforms::referenceTime(float slew) { - return ref_times_->findValue(slew); + return ref_times_.findValue(slew); } -Table1 +Table OutputWaveforms::voltageWaveform(float slew, float cap) { - FloatSeq *times = new FloatSeq; - FloatSeq *volts = new FloatSeq; + FloatSeq times; + FloatSeq volts; for (size_t i = 0; i <= voltage_waveform_step_count_; i++) { float volt = i * vdd_ / voltage_waveform_step_count_; float time = voltageTime(slew, cap, volt); - times->push_back(time); - volts->push_back(volt); + times.push_back(time); + volts.push_back(volt); } - TableAxisPtr time_axis = make_shared(TableAxisVariable::time, times); - return Table1(volts, time_axis); + TableAxisPtr time_axis = make_shared(TableAxisVariable::time, + std::move(times)); + return Table(std::move(volts), time_axis); } -const Table1 * +const Table * OutputWaveforms::voltageWaveformRaw(float slew, float cap) { @@ -1989,10 +2005,10 @@ OutputWaveforms::beginEndTime(float slew, size_t wave_index10 = (slew_index + 1) * cap_count + cap_index; size_t wave_index11 = (slew_index + 1) * cap_count + (cap_index + 1); - const Table1 *waveform00 = current_waveforms_[wave_index00]; - const Table1 *waveform01 = current_waveforms_[wave_index01]; - const Table1 *waveform10 = current_waveforms_[wave_index10]; - const Table1 *waveform11 = current_waveforms_[wave_index11]; + const Table *waveform00 = current_waveforms_[wave_index00]; + const Table *waveform01 = current_waveforms_[wave_index01]; + const Table *waveform10 = current_waveforms_[wave_index10]; + const Table *waveform11 = current_waveforms_[wave_index11]; // Interpolate waveform samples at voltage steps. size_t index1 = slew_index; @@ -2028,7 +2044,7 @@ OutputWaveforms::beginEndTime(float slew, return wave_value; } -Table1 +Table OutputWaveforms::voltageCurrentWaveform(float slew, float cap) { @@ -2041,8 +2057,9 @@ OutputWaveforms::voltageCurrentWaveform(float slew, currents->push_back(current); } TableAxisPtr volt_axis = - make_shared(TableAxisVariable::input_voltage, volts); - return Table1(currents, volt_axis); + make_shared(TableAxisVariable::input_voltage, std::move(*volts)); + delete volts; + return Table(currents, volt_axis); } // Incremental resistance at final value of waveform. @@ -2055,11 +2072,11 @@ OutputWaveforms::finalResistance() size_t cap_count = cap_axis_->size(); size_t cap_index = cap_count - 1; size_t wave_index = slew_index * cap_count + cap_index; - const Table1 *voltage_currents = voltage_currents_[wave_index]; - FloatSeq *voltages = voltage_currents->axis1()->values(); + const Table *voltage_currents = voltage_currents_[wave_index]; + const FloatSeq &voltages = voltage_currents->axis1()->values(); FloatSeq *currents = voltage_currents->values(); - size_t idx_last1 = voltages->size() - 2; - return (vdd_ - (*voltages)[idx_last1]) / abs((*currents)[idx_last1]); + size_t idx_last1 = voltages.size() - 2; + return (vdd_ - voltages[idx_last1]) / abs((*currents)[idx_last1]); } //////////////////////////////////////////////////////////////// @@ -2071,20 +2088,21 @@ DriverWaveform::DriverWaveform(const string &name, { } -Table1 +Table DriverWaveform::waveform(float slew) { const TableAxis *volt_axis = waveforms_->axis2(); FloatSeq *time_values = new FloatSeq; FloatSeq *volt_values = new FloatSeq; - for (float volt : *volt_axis->values()) { + for (float volt : volt_axis->values()) { float time = waveforms_->findValue(slew, volt, 0.0); time_values->push_back(time); volt_values->push_back(volt); } TableAxisPtr time_axis = make_shared(TableAxisVariable::time, - time_values); - Table1 waveform(volt_values, time_axis); + std::move(*time_values)); + delete time_values; + Table waveform(volt_values, time_axis); return waveform; } diff --git a/liberty/TimingArc.cc b/liberty/TimingArc.cc index 0a7acff5..347c56fe 100644 --- a/liberty/TimingArc.cc +++ b/liberty/TimingArc.cc @@ -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); diff --git a/power/Power.cc b/power/Power.cc index a10f1199..9c638c72 100644 --- a/power/Power.cc +++ b/power/Power.cc @@ -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 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; } } diff --git a/power/Power.hh b/power/Power.hh index 661f6e1f..1082af53 100644 --- a/power/Power.hh +++ b/power/Power.hh @@ -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); diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index 0c11320a..85ee1950 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -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()) diff --git a/sdf/ReportAnnotation.cc b/sdf/ReportAnnotation.cc index 63ecbcc6..c4e875b1 100644 --- a/sdf/ReportAnnotation.cc +++ b/sdf/ReportAnnotation.cc @@ -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++; } } diff --git a/sdf/SdfReader.cc b/sdf/SdfReader.cc index 8f695296..9e945130 100644 --- a/sdf/SdfReader.cc +++ b/sdf/SdfReader.cc @@ -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++; diff --git a/sdf/SdfReaderPvt.hh b/sdf/SdfReaderPvt.hh index 52bc1cf3..d5a623ab 100644 --- a/sdf/SdfReaderPvt.hh +++ b/sdf/SdfReaderPvt.hh @@ -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, diff --git a/sdf/SdfWriter.cc b/sdf/SdfWriter.cc index 23b055cb..f0095017 100644 --- a/sdf/SdfWriter.cc +++ b/sdf/SdfWriter.cc @@ -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_, " "); diff --git a/search/FindRegister.cc b/search/FindRegister.cc index f45f2391..a3607f61 100644 --- a/search/FindRegister.cc +++ b/search/FindRegister.cc @@ -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; } diff --git a/search/MakeTimingModel.cc b/search/MakeTimingModel.cc index 40e27ae2..7e3f89b8 100644 --- a/search/MakeTimingModel.cc +++ b/search/MakeTimingModel.cc @@ -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(value); + TablePtr table = make_shared
(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(delayAsFloat(delay)); - TablePtr slew_table = make_shared(delayAsFloat(slew)); + TablePtr delay_table = make_shared
(delayAsFloat(delay)); + TablePtr slew_table = make_shared
(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(delayAsFloat(delay)); + TablePtr delay_table = make_shared
(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(TableAxisVariable::total_output_net_capacitance, - axis_values); + std::move(axis_values)); - TablePtr delay_table = make_shared(load_values, load_axis); - TablePtr slew_table = make_shared(slew_values, load_axis); + TablePtr delay_table = make_shared
(load_values, load_axis); + TablePtr slew_table = make_shared
(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; diff --git a/search/Sim.cc b/search/Sim.cc index 70b6384e..19e47a2d 100644 --- a/search/Sim.cc +++ b/search/Sim.cc @@ -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; } } } diff --git a/search/Sta.cc b/search/Sta.cc index 7b7a2182..2257e95f 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -254,6 +254,7 @@ deleteAllMemory() deleteDelayCalcs(); PortDirection::destroy(); deleteLiberty(); + deleteTmpStrings(); } //////////////////////////////////////////////////////////////// diff --git a/spice/WriteSpice.cc b/spice/WriteSpice.cc index c6da6e22..cce1989b 100644 --- a/spice/WriteSpice.cc +++ b/spice/WriteSpice.cc @@ -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); diff --git a/spice/Xyce.cc b/spice/Xyce.cc index 618b65b1..f198df70 100644 --- a/spice/Xyce.cc +++ b/spice/Xyce.cc @@ -74,7 +74,7 @@ readXyceCsv(const char *csv_filename, } file.close(); TableAxisPtr time_axis = make_shared(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); } diff --git a/spice/Xyce.hh b/spice/Xyce.hh index c13a918b..1c27cb4e 100644 --- a/spice/Xyce.hh +++ b/spice/Xyce.hh @@ -32,7 +32,7 @@ namespace sta { using StdStringSeq = std::vector; -using WaveformSeq = std::vector; +using WaveformSeq = std::vector
; void readXyceCsv(const char *csv_filename, diff --git a/tcl/StaTclTypes.i b/tcl/StaTclTypes.i index e5b68051..a7a2d6eb 100644 --- a/tcl/StaTclTypes.i +++ b/tcl/StaTclTypes.i @@ -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); diff --git a/util/StringUtil.cc b/util/StringUtil.cc index 16237331..a0b8c154 100644 --- a/util/StringUtil.cc +++ b/util/StringUtil.cc @@ -186,6 +186,17 @@ thread_local static std::array tmp_strings; thread_local static std::array 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,