diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index 0da0a530..a18cceec 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -462,10 +462,12 @@ public: bool &exists) const; bool leakagePowerExists() const { return leakage_power_exists_; } - const SequentialSeq &sequentials() const { return sequentials_; } + // Register, Latch or Statetable. bool hasSequentials() const; + const SequentialSeq &sequentials() const { return sequentials_; } // Find the sequential with the output connected to an (internal) port. Sequential *outputPortSequential(LibertyPort *port); + const Statetable *statetable() const { return statetable_; } // Find bus declaration local to this cell. BusDcl *findBusDcl(const char *name) const; @@ -502,6 +504,9 @@ public: LogicValue clr_preset_out_inv, LibertyPort *output, LibertyPort *output_inv); + 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, @@ -600,6 +605,7 @@ protected: LeakagePowerSeq leakage_powers_; SequentialSeq sequentials_; PortToSequentialMap port_to_seq_map_; + Statetable *statetable_; BusDclMap bus_dcls_; ModeDefMap mode_defs_; ScaleFactors *scale_factors_; diff --git a/include/sta/LibertyClass.hh b/include/sta/LibertyClass.hh index 850e12e0..8217e031 100644 --- a/include/sta/LibertyClass.hh +++ b/include/sta/LibertyClass.hh @@ -24,6 +24,8 @@ namespace sta { +using std::vector; + class Units; class Unit; class LibertyLibrary; @@ -58,6 +60,8 @@ class Transition; class RiseFall; class RiseFallBoth; class ReceiverModel; +class Statetable; +class StatetableRow; typedef Vector LibertyLibrarySeq; typedef Vector LibertyCellSeq; @@ -71,6 +75,7 @@ typedef std::shared_ptr TablePtr; typedef std::shared_ptr TimingArcAttrsPtr; typedef std::shared_ptr TableAxisPtr; typedef std::shared_ptr ReceiverModelPtr; +typedef vector StatetableRows; enum class ScaleFactorType : unsigned { pin_cap, diff --git a/include/sta/Sequential.hh b/include/sta/Sequential.hh index 6f10b2cd..7d431f0e 100644 --- a/include/sta/Sequential.hh +++ b/include/sta/Sequential.hh @@ -16,11 +16,42 @@ #pragma once +#include + #include "LibertyClass.hh" #include "NetworkClass.hh" namespace sta { +enum class StateInputValue { + low, + high, + dont_care, + low_high, + high_low, + rise, + fall, + not_rise, + not_fall +}; + +enum class StateInternalValue { + low, + high, + unspecified, + low_high, + high_low, + unknown, + hold +}; + +class StatetableRow; + +using std::vector; + +typedef vector StateInputValues; +typedef vector StateInternalValues; + // Register/Latch class Sequential { @@ -63,8 +94,41 @@ protected: LibertyPort *output_; LibertyPort *output_inv_; -private: friend class LibertyCell; }; +class Statetable +{ +public: + const LibertyPortSeq &inputPorts() const { return input_ports_; } + const LibertyPortSeq &internalPorts() const { return internal_ports_; } + const StatetableRows &table() const { return table_; } + +protected: + Statetable(LibertyPortSeq &input_ports, + LibertyPortSeq &internal_ports, + StatetableRows &table); + LibertyPortSeq input_ports_; + LibertyPortSeq internal_ports_; + StatetableRows table_; + + friend class LibertyCell; +}; + +class StatetableRow +{ +public: + StatetableRow(StateInputValues &input_values, + StateInternalValues ¤t_values, + StateInternalValues &next_values); + const StateInputValues &inputValues() const { return input_values_; } + const StateInternalValues ¤tValues() const { return current_values_; } + const StateInternalValues &nextValues() const { return next_values_; } + +private: + StateInputValues input_values_; + StateInternalValues current_values_; + StateInternalValues next_values_; +}; + } // namespace diff --git a/liberty/EquivCells.cc b/liberty/EquivCells.cc index 84543d97..5e43cb98 100644 --- a/liberty/EquivCells.cc +++ b/liberty/EquivCells.cc @@ -38,6 +38,24 @@ hashCellPorts(const LibertyCell *cell); static unsigned hashCellSequentials(const LibertyCell *cell); static unsigned +hashSequential(const Sequential *seq); +bool +equivCellStatetables(const LibertyCell *cell1, + const LibertyCell *cell2); +static bool +equivCellPortSeq(const LibertyPortSeq &ports1, + const LibertyPortSeq &ports2); +static bool +equivStatetableRows(const StatetableRows &table1, + const StatetableRows &table2); +static bool +equivStatetableRow(const StatetableRow &row1, + const StatetableRow &row2); +static unsigned +hashStatetable(const Statetable *statetable); +static unsigned +hashStatetableRow(const StatetableRow &row); +static unsigned hashFuncExpr(const FuncExpr *expr); static unsigned hashPort(const LibertyPort *port); @@ -221,16 +239,61 @@ static unsigned hashCellSequentials(const LibertyCell *cell) { unsigned hash = 0; - for (Sequential *seq : cell->sequentials()) { - hash += hashFuncExpr(seq->clock()) * 3; - hash += hashFuncExpr(seq->data()) * 5; - hash += hashPort(seq->output()) * 7; - hash += hashPort(seq->outputInv()) * 9; - hash += hashFuncExpr(seq->clear()) * 11; - hash += hashFuncExpr(seq->preset()) * 13; - hash += int(seq->clearPresetOutput()) * 17; - hash += int(seq->clearPresetOutputInv()) * 19; - } + for (const Sequential *seq : cell->sequentials()) + hash += hashSequential(seq); + const Statetable *statetable = cell->statetable(); + if (statetable) + hash += hashStatetable(statetable); + return hash; +} + +static unsigned +hashSequential(const Sequential *seq) +{ + unsigned hash = 0; + hash += seq->isRegister() * 3; + hash += hashFuncExpr(seq->clock()) * 5; + hash += hashFuncExpr(seq->data()) * 7; + hash += hashPort(seq->output()) * 9; + hash += hashPort(seq->outputInv()) * 11; + hash += hashFuncExpr(seq->clear()) * 13; + hash += hashFuncExpr(seq->preset()) * 17; + hash += int(seq->clearPresetOutput()) * 19; + hash += int(seq->clearPresetOutputInv()) * 23; + return hash; +} + +static unsigned +hashStatetable(const Statetable *statetable) +{ + unsigned hash = 0; + unsigned hash_ports = 0; + for (LibertyPort *input_port : statetable->inputPorts()) + hash_ports += hashPort(input_port); + hash += hash_ports * 3; + + hash_ports = 0; + for (LibertyPort *internal_port : statetable->internalPorts()) + hash_ports += hashPort(internal_port); + hash += hash_ports * 5; + + unsigned hash_rows = 0; + for (const StatetableRow &row : statetable->table()) + hash_rows += hashStatetableRow(row); + hash += hash_rows * 7; + return hash; +} + +static unsigned +hashStatetableRow(const StatetableRow &row) +{ + unsigned hash = 0; + for (StateInputValue input_value : row.inputValues()) + hash += static_cast(input_value) * 9; + for (StateInternalValue current_value : row.currentValues()) + hash += static_cast(current_value) * 11; + for (StateInternalValue next_value : row.nextValues()) + hash += static_cast(next_value) * 13; return hash; } @@ -261,6 +324,7 @@ equivCells(const LibertyCell *cell1, return equivCellPortsAndFuncs(cell1, cell2) && equivCellPgPorts(cell1, cell2) && equivCellSequentials(cell1, cell2) + && equivCellStatetables(cell1, cell2) && equivCellTimingArcSets(cell1, cell2); } @@ -349,6 +413,102 @@ equivCellSequentials(const LibertyCell *cell1, return seq_itr1 == seqs1.end() && seq_itr2 == seqs2.end(); } +bool +equivCellStatetables(const LibertyCell *cell1, + const LibertyCell *cell2) + +{ + const Statetable *statetable1 = cell1->statetable(); + const Statetable *statetable2 = cell2->statetable(); + return (statetable1 == nullptr && statetable2 == nullptr) + || (statetable1 && statetable2 + && equivCellPortSeq(statetable1->inputPorts(), statetable2->inputPorts()) + && equivCellPortSeq(statetable1->internalPorts(), statetable2->internalPorts()) + && equivStatetableRows(statetable1->table(), statetable2->table())); +} + +static bool +equivCellPortSeq(const LibertyPortSeq &ports1, + const LibertyPortSeq &ports2) +{ + if (ports1.size() != ports2.size()) + return false; + + auto port_itr1 = ports1.begin(); + auto port_itr2 = ports2.begin(); + for (; + port_itr1 != ports1.end() && port_itr2 != ports2.end(); + port_itr1++, port_itr2++) { + const LibertyPort *port1 = *port_itr1; + const LibertyPort *port2 = *port_itr2; + if (!LibertyPort::equiv(port1, port2)) + return false; + } + return true; +} + +static bool +equivStatetableRows(const StatetableRows &table1, + const StatetableRows &table2) +{ + if (table1.size() != table2.size()) + return false; + + auto row_itr1 = table1.begin(); + auto row_itr2 = table2.begin(); + for (; + row_itr1 != table1.end() && row_itr2 != table2.end(); + row_itr1++, row_itr2++) { + const StatetableRow &row1 = *row_itr1; + const StatetableRow &row2 = *row_itr2; + if (!equivStatetableRow(row1, row2)) + return false; + } + return true; +} + +static bool +equivStatetableRow(const StatetableRow &row1, + const StatetableRow &row2) +{ + const StateInputValues &input_values1 = row1.inputValues(); + const StateInputValues &input_values2 = row2.inputValues(); + if (input_values1.size() != input_values2.size()) + return false; + for (auto input_itr1 = input_values1.begin(), + input_itr2 = input_values2.begin(); + input_itr1 != input_values1.end() && input_itr2 != input_values2.end(); + input_itr1++, input_itr2++) { + if (*input_itr1 != *input_itr2) + return false; + } + + const StateInternalValues ¤t_values1 = row1.currentValues(); + const StateInternalValues ¤t_values2 = row2.currentValues(); + if (current_values1.size() != current_values2.size()) + return false; + for (auto current_itr1 = current_values1.begin(), + current_itr2 = current_values2.begin(); + current_itr1 != current_values1.end() && current_itr2 != current_values2.end(); + current_itr1++, current_itr2++) { + if (*current_itr1 != *current_itr2) + return false; + } + + const StateInternalValues &next_values1 = row1.nextValues(); + const StateInternalValues &next_values2 = row2.nextValues(); + if (next_values1.size() != next_values2.size()) + return false; + for (auto next_itr1 = next_values1.begin(), + next_itr2 = next_values2.begin(); + next_itr1 != next_values1.end() && next_itr2 != next_values2.end(); + next_itr1++, next_itr2++) { + if (*next_itr1 != *next_itr2) + return false; + } + return true; +} + bool equivCellTimingArcSets(const LibertyCell *cell1, const LibertyCell *cell2) diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 96b24213..96b2a33d 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -930,6 +930,7 @@ LibertyCell::LibertyCell(LibertyLibrary *library, interface_timing_(false), clock_gate_type_(ClockGateType::none), has_infered_reg_timing_arcs_(false), + statetable_(nullptr), scale_factors_(nullptr), test_cell_(nullptr), ocv_arc_depth_(0.0), @@ -958,6 +959,7 @@ LibertyCell::~LibertyCell() leakage_powers_.deleteContents(); sequentials_.deleteContents(); + delete statetable_; bus_dcls_.deleteContents(); scaled_cells_.deleteContents(); @@ -1511,7 +1513,16 @@ LibertyCell::outputPortSequential(LibertyPort *port) bool LibertyCell::hasSequentials() const { - return !sequentials_.empty(); + return !sequentials_.empty() + || statetable_ != nullptr; +} + +void +LibertyCell::makeStatetable(LibertyPortSeq &input_ports, + LibertyPortSeq &internal_ports, + StatetableRows &table) +{ + statetable_ = new Statetable(input_ports, internal_ports, table); } void diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index 5f499842..d8064180 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -19,6 +19,7 @@ #include #include +#include "EnumNameMap.hh" #include "Report.hh" #include "Debug.hh" #include "TokenParser.hh" @@ -45,6 +46,7 @@ extern int LibertyParse_debug; namespace sta { using std::make_shared; +using std::string; static void scaleFloats(FloatSeq *floats, @@ -121,6 +123,7 @@ LibertyReader::readLibertyFile(const char *filename, in_bus_ = false; in_bundle_ = false; sequential_ = nullptr; + statetable_ = nullptr; timing_ = nullptr; internal_power_ = nullptr; leakage_power_ = nullptr; @@ -375,6 +378,11 @@ LibertyReader::defineVisitors() defineAttrVisitor("clear_preset_var1", &LibertyReader::visitClrPresetVar1); defineAttrVisitor("clear_preset_var2", &LibertyReader::visitClrPresetVar2); + // Statetable + defineGroupVisitor("statetable", &LibertyReader::beginStatetable, + &LibertyReader::endStatetable); + defineAttrVisitor("table", &LibertyReader::visitTable); + defineGroupVisitor("timing", &LibertyReader::beginTiming, &LibertyReader::endTiming); defineAttrVisitor("related_pin", &LibertyReader::visitRelatedPin); @@ -1904,6 +1912,7 @@ LibertyReader::endCell(LibertyGroup *group) // Sequentials and leakage powers reference expressions outside of port definitions // so they do not require LibertyFunc's. makeCellSequentials(); + makeStatetable(); // Parse functions defined inside of port groups that reference other ports // and replace the references with the parsed expressions. parseCellFuncs(); @@ -2126,6 +2135,37 @@ LibertyReader::checkLatchEnableSense(FuncExpr *enable_func, } } +//////////////////////////////////////////////////////////////// + +void +LibertyReader::makeStatetable() +{ + if (statetable_) { + LibertyPortSeq input_ports; + for (const string &input : statetable_->inputPorts()) { + LibertyPort *port = cell_->findLibertyPort(input.c_str()); + if (port) + input_ports.push_back(port); + else + libWarn(0000, statetable_->line(), "statetable input port %s not found.", + input.c_str()); + } + LibertyPortSeq internal_ports; + for (const string &internal : statetable_->internalPorts()) { + LibertyPort *port = cell_->findLibertyPort(internal.c_str()); + if (port) + internal_ports.push_back(port); + else + libWarn(0000, statetable_->line(), "statetable internal port %s not found.", + internal.c_str()); + } + cell_->makeStatetable(input_ports, internal_ports, statetable_->table()); + statetable_ = nullptr; + } +} + +//////////////////////////////////////////////////////////////// + void LibertyReader::makeLeakagePowers() { @@ -3928,6 +3968,134 @@ LibertyReader::visitClrPresetVar2(LibertyAttr *attr) //////////////////////////////////////////////////////////////// +void +LibertyReader::beginStatetable(LibertyGroup *group) +{ + if (cell_) { + const char *input_ports_arg = group->firstName(); + StdStringSeq input_ports; + if (input_ports_arg) + input_ports = parseTokenList(input_ports_arg, ' '); + + const char *internal_ports_arg = group->secondName(); + StdStringSeq internal_ports; + if (internal_ports_arg) + internal_ports = parseTokenList(internal_ports_arg, ' '); + statetable_ = new StatetableGroup(input_ports, internal_ports, group->line()); + } +} + +void +LibertyReader::visitTable(LibertyAttr *attr) +{ + if (statetable_) { + const char *table_str = getAttrString(attr); + StdStringSeq table_rows = parseTokenList(table_str, ','); + size_t input_count = statetable_->inputPorts().size(); + size_t internal_count = statetable_->internalPorts().size(); + for (string row : table_rows) { + StdStringSeq row_groups = parseTokenList(row.c_str(), ':'); + if (row_groups.size() != 3) { + libWarn(0000, attr, "table row must have 3 groups separated by ':'."); + break; + } + StdStringSeq inputs = parseTokenList(row_groups[0].c_str(), ' '); + if (inputs.size() != input_count) { + libWarn(0000, attr, "table row has %zu input values but %zu are required.", + inputs.size(), + input_count); + break; + } + StdStringSeq currents = parseTokenList(row_groups[1].c_str(), ' '); + if (currents.size() != internal_count) { + libWarn(0000, attr, "table row has %zu current values but %zu are required.", + currents.size(), + internal_count); + break; + } + StdStringSeq nexts = parseTokenList(row_groups[2].c_str(), ' '); + if (nexts.size() != internal_count) { + libWarn(0000, attr, "table row has %zu next values but %zu are required.", + nexts.size(), + internal_count); + break; + } + + StateInputValues input_values = parseStateInputValues(inputs, attr); + StateInternalValues current_values=parseStateInternalValues(currents,attr); + StateInternalValues next_values = parseStateInternalValues(nexts, attr); + statetable_->addRow(input_values, current_values, next_values); + } + } +} + +static EnumNameMap state_input_value_name_map = + {{StateInputValue::low, "L"}, + {StateInputValue::high, "H"}, + {StateInputValue::dont_care, "-"}, + {StateInputValue::low_high, "L/H"}, + {StateInputValue::high_low, "H/L"}, + {StateInputValue::rise, "R"}, + {StateInputValue::fall, "F"}, + {StateInputValue::not_rise, "~R"}, + {StateInputValue::not_fall, "~F"} + }; + +static EnumNameMap state_internal_value_name_map = + {{StateInternalValue::low, "L"}, + {StateInternalValue::high, "H"}, + {StateInternalValue::unspecified, "-"}, + {StateInternalValue::low_high, "L/H"}, + {StateInternalValue::high_low, "H/L"}, + {StateInternalValue::unknown, "X"}, + {StateInternalValue::hold, "N"} + }; + +StateInputValues +LibertyReader::parseStateInputValues(StdStringSeq &inputs, + LibertyAttr *attr) +{ + StateInputValues input_values; + for (string input : inputs) { + bool exists; + StateInputValue value; + state_input_value_name_map.find(input.c_str(), value, exists); + if (!exists) { + libWarn(0000, attr, "table input value '%s' not recognized.", + input.c_str()); + value = StateInputValue::dont_care; + } + input_values.push_back(value); + } + return input_values; +} + +StateInternalValues +LibertyReader::parseStateInternalValues(StdStringSeq &states, + LibertyAttr *attr) +{ + StateInternalValues state_values; + for (string state : states) { + bool exists; + StateInternalValue value; + state_internal_value_name_map.find(state.c_str(), value, exists); + if (!exists) { + libWarn(0000, attr, "table internal value '%s' not recognized.", + state.c_str()); + value = StateInternalValue::unknown; + } + state_values.push_back(value); + } + return state_values; +} + +void +LibertyReader::endStatetable(LibertyGroup *) +{ +} + +//////////////////////////////////////////////////////////////// + void LibertyReader::beginTiming(LibertyGroup *group) { @@ -3996,6 +4164,24 @@ LibertyReader::parseNameList(const char *name_list) return names; } +StdStringSeq +LibertyReader::parseTokenList(const char *token_str, + const char separator) +{ + StdStringSeq tokens; + // Parse space separated list of names. + char separators[2] = {separator, '\0'}; + TokenParser parser(token_str, separators); + while (parser.hasNext()) { + char *token = parser.next(); + // Skip extra spaces. + if (token[0] != '\0') { + tokens.push_back(token); + } + } + return tokens; +} + void LibertyReader::visitRelatedBusPins(LibertyAttr *attr) { @@ -5471,6 +5657,25 @@ SequentialGroup::setClrPresetVar2(LogicValue var) //////////////////////////////////////////////////////////////// +StatetableGroup::StatetableGroup(StdStringSeq &input_ports, + StdStringSeq &internal_ports, + int line) : + input_ports_(input_ports), + internal_ports_(internal_ports), + line_(line) +{ +} + +void +StatetableGroup::addRow(StateInputValues &input_values, + StateInternalValues ¤t_values, + StateInternalValues &next_values) +{ + table_.emplace_back(input_values, current_values, next_values); +} + +//////////////////////////////////////////////////////////////// + RelatedPortGroup::RelatedPortGroup(int line) : related_port_names_(nullptr), line_(line) diff --git a/liberty/LibertyReaderPvt.hh b/liberty/LibertyReaderPvt.hh index 5fc608a6..9a812f3c 100644 --- a/liberty/LibertyReaderPvt.hh +++ b/liberty/LibertyReaderPvt.hh @@ -17,6 +17,7 @@ #pragma once #include +#include #include "Vector.hh" #include "Map.hh" @@ -27,6 +28,7 @@ #include "InternalPower.hh" #include "LeakagePower.hh" #include "Liberty.hh" +#include "Sequential.hh" #include "LibertyParser.hh" #include "LibertyReader.hh" #include "NetworkClass.hh" @@ -38,6 +40,7 @@ class LibertyReader; class LibertyFunc; class PortGroup; class SequentialGroup; +class StatetableGroup; class RelatedPortGroup; class TimingGroup; class InternalPowerGroup; @@ -47,6 +50,8 @@ class TimingArcBuilder; class LibertyAttr; class OutputWaveform; +using std::vector; + typedef void (LibertyReader::*LibraryAttrVisitor)(LibertyAttr *attr); typedef void (LibertyReader::*LibraryGroupVisitor)(LibertyGroup *group); typedef Map LibraryAttrMap; @@ -59,6 +64,7 @@ typedef Vector InternalPowerGroupSeq; typedef Vector LeakagePowerGroupSeq; typedef void (LibertyPort::*LibertyPortBoolSetter)(bool value); typedef Vector OutputWaveformSeq; +typedef vector StdStringSeq; class LibertyReader : public LibertyGroupVisitor { @@ -164,6 +170,7 @@ public: virtual void makeInternalPowers(PortGroup *port_group); virtual void makeCellSequentials(); virtual void makeCellSequential(SequentialGroup *seq); + virtual void makeStatetable(); virtual void makeLeakagePowers(); virtual void parseCellFuncs(); virtual void makeLibertyFunc(const char *expr, @@ -302,6 +309,10 @@ public: virtual void visitClrPresetVar1(LibertyAttr *attr); virtual void visitClrPresetVar2(LibertyAttr *attr); + virtual void beginStatetable(LibertyGroup *group); + virtual void endStatetable(LibertyGroup *group); + virtual void visitTable(LibertyAttr *attr); + virtual void beginTiming(LibertyGroup *group); virtual void endTiming(LibertyGroup *group); virtual void visitRelatedPin(LibertyAttr *attr); @@ -502,12 +513,19 @@ protected: void makeTableAxis(int index); StringSeq *parseNameList(const char *name_list); + StdStringSeq parseTokenList(const char *token_str, + const char separator); LibertyPort *findPort(const char *port_name); LibertyPort *findPort(LibertyCell *cell, const char *port_name); float defaultCap(LibertyPort *port); virtual void visitVariable(LibertyVariable *var); void visitPorts(std::function func); + StateInputValues parseStateInputValues(StdStringSeq &inputs, + LibertyAttr *attr); + StateInternalValues parseStateInternalValues(StdStringSeq &states, + LibertyAttr *attr); + const char *getAttrString(LibertyAttr *attr); void getAttrInt(LibertyAttr *attr, // Return values. @@ -610,6 +628,7 @@ protected: bool type_bit_to_exists_; SequentialGroup *sequential_; SequentialGroupSeq cell_sequentials_; + StatetableGroup *statetable_; TimingGroup *timing_; InternalPowerGroup *internal_power_; LeakagePowerGroup *leakage_power_; @@ -703,6 +722,24 @@ private: int line_; }; +// Liberty group with related_pins group attribute. +class RelatedPortGroup +{ +public: + explicit RelatedPortGroup(int line); + virtual ~RelatedPortGroup(); + int line() const { return line_; } + StringSeq *relatedPortNames() const { return related_port_names_; } + void setRelatedPortNames(StringSeq *names); + bool isOneToOne() const { return is_one_to_one_; } + void setIsOneToOne(bool one); + +protected: + StringSeq *related_port_names_; + bool is_one_to_one_; + int line_; +}; + class SequentialGroup { public: @@ -747,21 +784,24 @@ protected: int line_; }; -// Liberty group with related_pins group attribute. -class RelatedPortGroup +class StatetableGroup { public: - explicit RelatedPortGroup(int line); - virtual ~RelatedPortGroup(); + StatetableGroup(StdStringSeq &input_ports, + StdStringSeq &internal_ports, + int line); + const StdStringSeq &inputPorts() const { return input_ports_; } + const StdStringSeq &internalPorts() const { return internal_ports_; } + void addRow(StateInputValues &input_values, + StateInternalValues ¤t_values, + StateInternalValues &next_values); + StatetableRows &table() { return table_; } int line() const { return line_; } - StringSeq *relatedPortNames() const { return related_port_names_; } - void setRelatedPortNames(StringSeq *names); - bool isOneToOne() const { return is_one_to_one_; } - void setIsOneToOne(bool one); -protected: - StringSeq *related_port_names_; - bool is_one_to_one_; +private: + StdStringSeq input_ports_; + StdStringSeq internal_ports_; + StatetableRows table_; int line_; }; diff --git a/liberty/Sequential.cc b/liberty/Sequential.cc index 3348789f..970798de 100644 --- a/liberty/Sequential.cc +++ b/liberty/Sequential.cc @@ -53,4 +53,24 @@ Sequential::~Sequential() preset_->deleteSubexprs(); } +//////////////////////////////////////////////////////////////// + +Statetable::Statetable(LibertyPortSeq &input_ports, + LibertyPortSeq &internal_ports, + StatetableRows &table) : + input_ports_(input_ports), + internal_ports_(internal_ports), + table_(table) +{ +} + +StatetableRow::StatetableRow(StateInputValues &input_values, + StateInternalValues ¤t_values, + StateInternalValues &next_values) : + input_values_(input_values), + current_values_(current_values), + next_values_(next_values) +{ +} + } // namespace diff --git a/power/Power.cc b/power/Power.cc index 93f4cd59..7cb6628c 100644 --- a/power/Power.cc +++ b/power/Power.cc @@ -244,10 +244,10 @@ Power::power(const Corner *corner, macro.incr(inst_power); else if (cell->isPad()) pad.incr(inst_power); - else if (cell->hasSequentials()) - sequential.incr(inst_power); else if (inClockNetwork(inst)) clock.incr(inst_power); + else if (cell->hasSequentials()) + sequential.incr(inst_power); else combinational.incr(inst_power); total.incr(inst_power);