liberty upf accessors
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
9bdd01f01a
commit
333b91e72d
|
|
@ -88,6 +88,12 @@ constexpr int scale_factor_pvt_count = int(ScaleFactorPvt::unknown) + 1;
|
|||
enum class TableTemplateType { delay, power, output_current, ocv };
|
||||
constexpr int table_template_type_count = int(TableTemplateType::ocv) + 1;
|
||||
|
||||
enum class LevelShifterType { HL, LH, HL_LH };
|
||||
|
||||
enum class SwitchCellType { coarse_grain, fine_grain };
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
initLiberty();
|
||||
void
|
||||
|
|
@ -117,6 +123,8 @@ timingSenseString(TimingSense sense);
|
|||
TimingSense
|
||||
timingSenseOpposite(TimingSense sense);
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
class LibertyLibrary : public ConcreteLibrary
|
||||
{
|
||||
public:
|
||||
|
|
@ -145,6 +153,7 @@ public:
|
|||
void setNominalVoltage(float voltage);
|
||||
float nominalTemperature() const { return nominal_temperature_; }
|
||||
void setNominalTemperature(float temperature);
|
||||
|
||||
void setScaleFactors(ScaleFactors *scales);
|
||||
// Add named scale factor group.
|
||||
void addScaleFactors(ScaleFactors *scales);
|
||||
|
|
@ -159,6 +168,7 @@ public:
|
|||
int tr_index,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt) const;
|
||||
|
||||
void setWireSlewDegradationTable(TableModel *model,
|
||||
RiseFall *rf);
|
||||
TableModel *wireSlewDegradationTable(const RiseFall *rf) const;
|
||||
|
|
@ -173,8 +183,10 @@ public:
|
|||
|
||||
float defaultInputPinCap() const { return default_input_pin_cap_; }
|
||||
void setDefaultInputPinCap(float cap);
|
||||
|
||||
float defaultOutputPinCap() const { return default_output_pin_cap_; }
|
||||
void setDefaultOutputPinCap(float cap);
|
||||
|
||||
float defaultBidirectPinCap() const { return default_bidirect_pin_cap_; }
|
||||
void setDefaultBidirectPinCap(float cap);
|
||||
|
||||
|
|
@ -196,6 +208,7 @@ public:
|
|||
bool &exists) const;
|
||||
void setDefaultBidirectPinRes(const RiseFall *rf,
|
||||
float value);
|
||||
|
||||
void defaultOutputPinRes(const RiseFall *rf,
|
||||
// Return values.
|
||||
float &res,
|
||||
|
|
@ -206,12 +219,15 @@ public:
|
|||
void defaultMaxSlew(float &slew,
|
||||
bool &exists) const;
|
||||
void setDefaultMaxSlew(float slew);
|
||||
|
||||
void defaultMaxCapacitance(float &cap,
|
||||
bool &exists) const;
|
||||
void setDefaultMaxCapacitance(float cap);
|
||||
|
||||
void defaultMaxFanout(float &fanout,
|
||||
bool &exists) const;
|
||||
void setDefaultMaxFanout(float fanout);
|
||||
|
||||
void defaultFanoutLoad(// Return values.
|
||||
float &fanout,
|
||||
bool &exists) const;
|
||||
|
|
@ -248,7 +264,6 @@ public:
|
|||
Wireload *defaultWireload() const;
|
||||
WireloadSelection *findWireloadSelection(const char *name) const;
|
||||
WireloadSelection *defaultWireloadSelection() const;
|
||||
|
||||
void addWireload(Wireload *wireload);
|
||||
WireloadMode defaultWireloadMode() const;
|
||||
void setDefaultWireloadMode(WireloadMode mode);
|
||||
|
|
@ -405,6 +420,14 @@ public:
|
|||
void setIsPad(bool is_pad);
|
||||
bool isLevelShifter() const { return is_level_shifter_; }
|
||||
void setIsLevelShifter(bool is_level_shifter);
|
||||
LevelShifterType levelShifterType() const { return level_shifter_type_; }
|
||||
void setLevelShifterType(LevelShifterType level_shifter_type);
|
||||
bool isIsolationCell() const { return is_isolation_cell_; }
|
||||
void setIsIsolationCell(bool is_isolation_cell);
|
||||
bool alwaysOn() const { return always_on_; }
|
||||
void setAlwaysOn(bool always_on);
|
||||
SwitchCellType switchCellType() const { return switch_cell_type_; }
|
||||
void setSwitchCellType(SwitchCellType switch_cell_type);
|
||||
bool interfaceTiming() const { return interface_timing_; }
|
||||
void setInterfaceTiming(bool value);
|
||||
bool isClockGateLatchPosedge() const;
|
||||
|
|
@ -537,7 +560,10 @@ protected:
|
|||
bool is_memory_;
|
||||
bool is_pad_;
|
||||
bool is_level_shifter_;
|
||||
bool has_internal_ports_;
|
||||
LevelShifterType level_shifter_type_;
|
||||
bool is_isolation_cell_;
|
||||
bool always_on_;
|
||||
SwitchCellType switch_cell_type_;
|
||||
bool interface_timing_;
|
||||
ClockGateType clock_gate_type_;
|
||||
TimingArcSetSeq timing_arc_sets_;
|
||||
|
|
@ -571,6 +597,7 @@ protected:
|
|||
float leakage_power_;
|
||||
bool leakage_power_exists_;
|
||||
LibertyPgPortMap pg_port_map_;
|
||||
bool has_internal_ports_;
|
||||
|
||||
private:
|
||||
friend class LibertyLibrary;
|
||||
|
|
@ -713,6 +740,19 @@ public:
|
|||
void setIsClockGateOutPin(bool is_clk_gate_out);
|
||||
bool isPllFeedbackPin() const { return is_pll_feedback_pin_; }
|
||||
void setIsPllFeedbackPin(bool is_pll_feedback_pin);
|
||||
|
||||
bool isolationCellDataPin() const { return isolation_cell_data_pin_; }
|
||||
void setIsolationCellDataPin(bool isolation_cell_data_pin);
|
||||
|
||||
bool isolationCellEnablePin() const { return isolation_cell_enable_pin_; }
|
||||
void setIsolationCellEnablePin(bool isolation_cell_enable_pin);
|
||||
|
||||
bool levelShifterDataPin() const { return level_shifter_data_pin_; }
|
||||
void setLevelShifterDataPin(bool level_shifter_data_pin);
|
||||
|
||||
bool switchPin() const { return switch_pin_; }
|
||||
void setSwitchPin(bool switch_pin);
|
||||
|
||||
// Has register/latch rise/fall edges from pin.
|
||||
bool isRegClk() const { return is_reg_clk_; }
|
||||
void setIsRegClk(bool is_clk);
|
||||
|
|
@ -789,6 +829,10 @@ protected:
|
|||
bool is_clk_gate_enable_pin_:1;
|
||||
bool is_clk_gate_out_pin_:1;
|
||||
bool is_pll_feedback_pin_:1;
|
||||
bool isolation_cell_data_pin_:1;
|
||||
bool isolation_cell_enable_pin_:1;
|
||||
bool level_shifter_data_pin_:1;
|
||||
bool switch_pin_:1;
|
||||
bool is_disabled_constraint_:1;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -891,7 +891,10 @@ LibertyCell::LibertyCell(LibertyLibrary *library,
|
|||
is_memory_(false),
|
||||
is_pad_(false),
|
||||
is_level_shifter_(false),
|
||||
has_internal_ports_(false),
|
||||
level_shifter_type_(LevelShifterType::HL_LH),
|
||||
is_isolation_cell_(false),
|
||||
always_on_(false),
|
||||
switch_cell_type_(SwitchCellType::fine_grain),
|
||||
interface_timing_(false),
|
||||
clock_gate_type_(ClockGateType::none),
|
||||
has_infered_reg_timing_arcs_(false),
|
||||
|
|
@ -901,7 +904,8 @@ LibertyCell::LibertyCell(LibertyLibrary *library,
|
|||
ocv_derate_(nullptr),
|
||||
is_disabled_constraint_(false),
|
||||
leakage_power_(0.0),
|
||||
leakage_power_exists_(false)
|
||||
leakage_power_exists_(false),
|
||||
has_internal_ports_(false)
|
||||
{
|
||||
liberty_cell_ = this;
|
||||
}
|
||||
|
|
@ -1038,11 +1042,35 @@ LibertyCell::LibertyCell::setIsPad(bool is_pad)
|
|||
}
|
||||
|
||||
void
|
||||
LibertyCell::LibertyCell::setIsLevelShifter(bool is_level_shifter)
|
||||
LibertyCell::setIsLevelShifter(bool is_level_shifter)
|
||||
{
|
||||
is_level_shifter_ = is_level_shifter;
|
||||
}
|
||||
|
||||
void
|
||||
LibertyCell::setLevelShifterType(LevelShifterType level_shifter_type)
|
||||
{
|
||||
level_shifter_type_ = level_shifter_type;
|
||||
}
|
||||
|
||||
void
|
||||
LibertyCell::setIsIsolationCell(bool is_isolation_cell)
|
||||
{
|
||||
is_isolation_cell_ = is_isolation_cell;
|
||||
}
|
||||
|
||||
void
|
||||
LibertyCell::setAlwaysOn(bool always_on)
|
||||
{
|
||||
always_on_ = always_on;
|
||||
}
|
||||
|
||||
void
|
||||
LibertyCell::setSwitchCellType(SwitchCellType switch_cell_type)
|
||||
{
|
||||
switch_cell_type_ = switch_cell_type;
|
||||
}
|
||||
|
||||
void
|
||||
LibertyCell::setInterfaceTiming(bool value)
|
||||
{
|
||||
|
|
@ -1898,6 +1926,10 @@ LibertyPort::LibertyPort(LibertyCell *cell,
|
|||
is_clk_gate_enable_pin_(false),
|
||||
is_clk_gate_out_pin_(false),
|
||||
is_pll_feedback_pin_(false),
|
||||
isolation_cell_data_pin_(false),
|
||||
isolation_cell_enable_pin_(false),
|
||||
level_shifter_data_pin_(false),
|
||||
switch_pin_(false),
|
||||
is_disabled_constraint_(false)
|
||||
{
|
||||
liberty_port_ = this;
|
||||
|
|
@ -2351,6 +2383,30 @@ LibertyPort::setIsPllFeedbackPin(bool is_pll_feedback_pin)
|
|||
is_pll_feedback_pin_ = is_pll_feedback_pin;
|
||||
}
|
||||
|
||||
void
|
||||
LibertyPort::setIsolationCellDataPin(bool isolation_cell_data_pin)
|
||||
{
|
||||
isolation_cell_data_pin_ = isolation_cell_data_pin;
|
||||
}
|
||||
|
||||
void
|
||||
LibertyPort::setIsolationCellEnablePin(bool isolation_cell_enable_pin)
|
||||
{
|
||||
isolation_cell_enable_pin_ = isolation_cell_enable_pin;
|
||||
}
|
||||
|
||||
void
|
||||
LibertyPort::setLevelShifterDataPin(bool level_shifter_data_pin)
|
||||
{
|
||||
level_shifter_data_pin_ = level_shifter_data_pin;
|
||||
}
|
||||
|
||||
void
|
||||
LibertyPort::setSwitchPin(bool switch_pin)
|
||||
{
|
||||
switch_pin_ = switch_pin;
|
||||
}
|
||||
|
||||
void
|
||||
LibertyPort::setPulseClk(RiseFall *trigger,
|
||||
RiseFall *sense)
|
||||
|
|
|
|||
|
|
@ -164,6 +164,7 @@ LibertyReader::defineAttrVisitor(const char *attr_name,
|
|||
void
|
||||
LibertyReader::defineVisitors()
|
||||
{
|
||||
// Library
|
||||
defineGroupVisitor("library", &LibertyReader::beginLibrary,
|
||||
&LibertyReader::endLibrary);
|
||||
defineAttrVisitor("time_unit", &LibertyReader::visitTimeUnit);
|
||||
|
|
@ -281,6 +282,7 @@ LibertyReader::defineVisitors()
|
|||
defineAttrVisitor("wire_load_from_area",
|
||||
&LibertyReader::visitWireloadFromArea);
|
||||
|
||||
// Cells
|
||||
defineGroupVisitor("cell", &LibertyReader::beginCell,
|
||||
&LibertyReader::endCell);
|
||||
defineGroupVisitor("scaled_cell", &LibertyReader::beginScaledCell,
|
||||
|
|
@ -293,9 +295,14 @@ LibertyReader::defineVisitors()
|
|||
defineAttrVisitor("is_memory", &LibertyReader::visitIsMemory);
|
||||
defineAttrVisitor("is_pad", &LibertyReader::visitIsPad);
|
||||
defineAttrVisitor("is_level_shifter", &LibertyReader::visitIsLevelShifter);
|
||||
defineAttrVisitor("level_shifter_type", &LibertyReader::visitLevelShifterType);
|
||||
defineAttrVisitor("is_isolation_cell", &LibertyReader::visitIsIsolationCell);
|
||||
defineAttrVisitor("always_on", &LibertyReader::visitAlwaysOn);
|
||||
defineAttrVisitor("switch_cell_type", &LibertyReader::visitSwitchCellType);
|
||||
defineAttrVisitor("interface_timing", &LibertyReader::visitInterfaceTiming);
|
||||
defineAttrVisitor("scaling_factors", &LibertyReader::visitScalingFactors);
|
||||
|
||||
// Pins
|
||||
defineGroupVisitor("pin", &LibertyReader::beginPin,&LibertyReader::endPin);
|
||||
defineGroupVisitor("bus", &LibertyReader::beginBus,&LibertyReader::endBus);
|
||||
defineGroupVisitor("bundle", &LibertyReader::beginBundle,
|
||||
|
|
@ -337,6 +344,15 @@ LibertyReader::defineVisitors()
|
|||
&LibertyReader::visitIsPllFeedbackPin);
|
||||
defineAttrVisitor("signal_type", &LibertyReader::visitSignalType);
|
||||
|
||||
defineAttrVisitor("isolation_cell_data_pin",
|
||||
&LibertyReader::visitIsolationCellDataPin);
|
||||
defineAttrVisitor("isolation_cell_enable_pin",
|
||||
&LibertyReader::visitIsolationCellEnablePin);
|
||||
defineAttrVisitor("level_shifter_data_pin",
|
||||
&LibertyReader::visitLevelShifterDataPin);
|
||||
defineAttrVisitor("switch_pin", &LibertyReader::visitSwitchPin);
|
||||
|
||||
// Register/latch
|
||||
defineGroupVisitor("ff", &LibertyReader::beginFF, &LibertyReader::endFF);
|
||||
defineGroupVisitor("ff_bank", &LibertyReader::beginFFBank,
|
||||
&LibertyReader::endFFBank);
|
||||
|
|
@ -2502,6 +2518,58 @@ LibertyReader::visitIsLevelShifter(LibertyAttr *attr)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::visitLevelShifterType(LibertyAttr *attr)
|
||||
{
|
||||
if (cell_) {
|
||||
const char *level_shifter_type = getAttrString(attr);
|
||||
if (stringEq(level_shifter_type, "HL"))
|
||||
cell_->setLevelShifterType(LevelShifterType::HL);
|
||||
else if (stringEq(level_shifter_type, "LH"))
|
||||
cell_->setLevelShifterType(LevelShifterType::LH);
|
||||
else if (stringEq(level_shifter_type, "HL_LH"))
|
||||
cell_->setLevelShifterType(LevelShifterType::HL_LH);
|
||||
else
|
||||
libWarn(900, attr, "level_shifter_type must be HL, LH, or HL_LH");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::visitIsIsolationCell(LibertyAttr *attr)
|
||||
{
|
||||
if (cell_) {
|
||||
bool is_isolation_cell, exists;
|
||||
getAttrBool(attr, is_isolation_cell, exists);
|
||||
if (exists)
|
||||
cell_->setIsIsolationCell(is_isolation_cell);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::visitAlwaysOn(LibertyAttr *attr)
|
||||
{
|
||||
if (cell_) {
|
||||
bool always_on, exists;
|
||||
getAttrBool(attr, always_on, exists);
|
||||
if (exists)
|
||||
cell_->setAlwaysOn(always_on);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::visitSwitchCellType(LibertyAttr *attr)
|
||||
{
|
||||
if (cell_) {
|
||||
const char *switch_cell_type = getAttrString(attr);
|
||||
if (stringEq(switch_cell_type, "coarse_grain"))
|
||||
cell_->setSwitchCellType(SwitchCellType::coarse_grain);
|
||||
else if (stringEq(switch_cell_type, "fine_grain"))
|
||||
cell_->setSwitchCellType(SwitchCellType::fine_grain);
|
||||
else
|
||||
libWarn(901, attr, "switch_cell_type must be coarse_grain or fine_grain");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::visitInterfaceTiming(LibertyAttr *attr)
|
||||
{
|
||||
|
|
@ -3223,65 +3291,25 @@ LibertyReader::visitPulseClock(LibertyAttr *attr)
|
|||
void
|
||||
LibertyReader::visitClockGateClockPin(LibertyAttr *attr)
|
||||
{
|
||||
if (cell_) {
|
||||
bool value, exists;
|
||||
getAttrBool(attr, value, exists);
|
||||
if (exists) {
|
||||
LibertyPortSeq::Iterator port_iter(ports_);
|
||||
while (port_iter.hasNext()) {
|
||||
LibertyPort *port = port_iter.next();
|
||||
port->setIsClockGateClockPin(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
visitPortBoolAttr(attr, &LibertyPort::setIsClockGateClockPin);
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::visitClockGateEnablePin(LibertyAttr *attr)
|
||||
{
|
||||
if (cell_) {
|
||||
bool value, exists;
|
||||
getAttrBool(attr, value, exists);
|
||||
if (exists) {
|
||||
LibertyPortSeq::Iterator port_iter(ports_);
|
||||
while (port_iter.hasNext()) {
|
||||
LibertyPort *port = port_iter.next();
|
||||
port->setIsClockGateEnablePin(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
visitPortBoolAttr(attr, &LibertyPort::setIsClockGateEnablePin);
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::visitClockGateOutPin(LibertyAttr *attr)
|
||||
{
|
||||
if (cell_) {
|
||||
bool value, exists;
|
||||
getAttrBool(attr, value, exists);
|
||||
if (exists) {
|
||||
LibertyPortSeq::Iterator port_iter(ports_);
|
||||
while (port_iter.hasNext()) {
|
||||
LibertyPort *port = port_iter.next();
|
||||
port->setIsClockGateOutPin(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
visitPortBoolAttr(attr, &LibertyPort::setIsClockGateOutPin);
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::visitIsPllFeedbackPin(LibertyAttr *attr)
|
||||
{
|
||||
if (cell_) {
|
||||
bool value, exists;
|
||||
getAttrBool(attr, value, exists);
|
||||
if (exists) {
|
||||
LibertyPortSeq::Iterator port_iter(ports_);
|
||||
while (port_iter.hasNext()) {
|
||||
LibertyPort *port = port_iter.next();
|
||||
port->setIsPllFeedbackPin(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
visitPortBoolAttr(attr, &LibertyPort::setIsPllFeedbackPin);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3302,6 +3330,47 @@ LibertyReader::visitSignalType(LibertyAttr *attr)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::visitIsolationCellDataPin(LibertyAttr *attr)
|
||||
{
|
||||
visitPortBoolAttr(attr, &LibertyPort::setIsolationCellDataPin);
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::visitIsolationCellEnablePin(LibertyAttr *attr)
|
||||
{
|
||||
visitPortBoolAttr(attr, &LibertyPort::setIsolationCellEnablePin);
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::visitLevelShifterDataPin(LibertyAttr *attr)
|
||||
{
|
||||
visitPortBoolAttr(attr, &LibertyPort::setLevelShifterDataPin);
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::visitSwitchPin(LibertyAttr *attr)
|
||||
{
|
||||
visitPortBoolAttr(attr, &LibertyPort::setSwitchPin);
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::visitPortBoolAttr(LibertyAttr *attr,
|
||||
LibertyPortBoolSetter setter)
|
||||
{
|
||||
if (cell_) {
|
||||
bool value, exists;
|
||||
getAttrBool(attr, value, exists);
|
||||
if (exists) {
|
||||
LibertyPortSeq::Iterator port_iter(ports_);
|
||||
while (port_iter.hasNext()) {
|
||||
LibertyPort *port = port_iter.next();
|
||||
(port->*setter)(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ typedef Vector<LibertyFunc*> LibertyFuncSeq;
|
|||
typedef Vector<TimingGroup*> TimingGroupSeq;
|
||||
typedef Vector<InternalPowerGroup*> InternalPowerGroupSeq;
|
||||
typedef Vector<LeakagePowerGroup*> LeakagePowerGroupSeq;
|
||||
typedef void (LibertyPort::*LibertyPortBoolSetter)(bool value);
|
||||
|
||||
class LibertyReader : public LibertyGroupVisitor
|
||||
{
|
||||
|
|
@ -182,7 +183,11 @@ public:
|
|||
virtual void visitIsMacro(LibertyAttr *attr);
|
||||
virtual void visitIsMemory(LibertyAttr *attr);
|
||||
virtual void visitIsPad(LibertyAttr *attr);
|
||||
void visitIsLevelShifter(LibertyAttr *attr);
|
||||
virtual void visitIsLevelShifter(LibertyAttr *attr);
|
||||
virtual void visitLevelShifterType(LibertyAttr *attr);
|
||||
virtual void visitIsIsolationCell(LibertyAttr *attr);
|
||||
virtual void visitAlwaysOn(LibertyAttr *attr);
|
||||
virtual void visitSwitchCellType(LibertyAttr *attr);
|
||||
virtual void visitInterfaceTiming(LibertyAttr *attr);
|
||||
virtual void visitScalingFactors(LibertyAttr *attr);
|
||||
virtual void visitCellLeakagePower(LibertyAttr *attr);
|
||||
|
|
@ -233,6 +238,12 @@ public:
|
|||
virtual void visitSignalType(LibertyAttr *attr);
|
||||
EarlyLateAll *getAttrEarlyLate(LibertyAttr *attr);
|
||||
virtual void visitClock(LibertyAttr *attr);
|
||||
virtual void visitIsolationCellDataPin(LibertyAttr *attr);
|
||||
virtual void visitIsolationCellEnablePin(LibertyAttr *attr);
|
||||
virtual void visitLevelShifterDataPin(LibertyAttr *attr);
|
||||
virtual void visitSwitchPin(LibertyAttr *attr);
|
||||
void visitPortBoolAttr(LibertyAttr *attr,
|
||||
LibertyPortBoolSetter setter);
|
||||
|
||||
virtual void beginScalingFactors(LibertyGroup *group);
|
||||
virtual void endScalingFactors(LibertyGroup *group);
|
||||
|
|
|
|||
Loading…
Reference in New Issue