liberty upf accessors

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2022-11-18 12:08:34 -07:00
parent 9bdd01f01a
commit 333b91e72d
4 changed files with 230 additions and 50 deletions

View File

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

View File

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

View File

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

View File

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