issue40 liberty multi-segment receiver capacitance

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2024-06-11 21:07:03 -07:00
parent 113e917c01
commit fcbb1840ab
4 changed files with 38 additions and 17 deletions

View File

@ -469,15 +469,14 @@ private:
class ReceiverModel
{
public:
ReceiverModel();
~ReceiverModel();
void setCapacitanceModel(TableModel *table_model,
int index,
size_t segment,
RiseFall *rf);
static bool checkAxes(TablePtr table);
private:
TableModel *capacitance_models_[2][RiseFall::index_count];
std::vector<TableModel*> capacitance_models_;
};
// Two dimensional (slew/cap) table of one dimensional time/current tables.

View File

@ -478,10 +478,19 @@ LibertyReader::defineVisitors()
defineAttrVisitor("pg_type", &LibertyReader::visitPgType);
defineAttrVisitor("voltage_name", &LibertyReader::visitVoltageName);
// ccs receiver
// ccs receiver capacitance
defineGroupVisitor("receiver_capacitance",
&LibertyReader::beginReceiverCapacitance,
&LibertyReader::endReceiverCapacitance);
defineGroupVisitor("receiver_capacitance_rise",
&LibertyReader::beginReceiverCapacitance1Rise,
&LibertyReader::endReceiverCapacitanceRiseFall);
defineGroupVisitor("receiver_capacitance_fall",
&LibertyReader::beginReceiverCapacitance1Fall,
&LibertyReader::endReceiverCapacitanceRiseFall);
defineAttrVisitor("segment", &LibertyReader::visitSegement);
defineGroupVisitor("receiver_capacitance1_rise",
&LibertyReader::beginReceiverCapacitance1Rise,
&LibertyReader::endReceiverCapacitanceRiseFall);
@ -2448,10 +2457,10 @@ LibertyReader::makeTimingArcs(LibertyPort *to_port,
////////////////////////////////////////////////////////////////
// Group that encloses receiver_capacitance1/2 etc groups.
void
LibertyReader::beginReceiverCapacitance(LibertyGroup *)
{
receiver_model_ = make_shared<ReceiverModel>();
}
@ -2465,6 +2474,20 @@ LibertyReader::endReceiverCapacitance(LibertyGroup *)
receiver_model_ = nullptr;
}
// For receiver_capacitance groups with mulitiple segments this
// overrides the index passed in beginReceiverCapacitance1Rise/Fall.
void
LibertyReader::visitSegement(LibertyAttr *attr)
{
if (receiver_model_) {
int segment;
bool exists;
getAttrInt(attr, segment, exists);
if (exists)
index_ = segment;
}
}
void
LibertyReader::beginReceiverCapacitance1Rise(LibertyGroup *group)
{

View File

@ -424,9 +424,12 @@ public:
virtual void visitPgType(LibertyAttr *attr);
virtual void visitVoltageName(LibertyAttr *attr);
// ccs receiver
// ccs receiver capacitance
virtual void beginReceiverCapacitance(LibertyGroup *group);
virtual void endReceiverCapacitance(LibertyGroup *group);
virtual void visitSegement(LibertyAttr *attr);
virtual void beginReceiverCapacitance1Rise(LibertyGroup *group);
virtual void endReceiverCapacitanceRiseFall(LibertyGroup *group);
virtual void beginReceiverCapacitance1Fall(LibertyGroup *group);

View File

@ -355,25 +355,21 @@ GateTableModel::checkAxis(const TableAxis *axis)
////////////////////////////////////////////////////////////////
ReceiverModel::ReceiverModel() :
capacitance_models_{{nullptr, nullptr}, {nullptr, nullptr}}
{
}
ReceiverModel::~ReceiverModel()
{
for (int index = 0; index < 2; index++) {
for (auto rf_index : RiseFall::rangeIndex())
delete capacitance_models_[index][rf_index];
}
for (TableModel *model : capacitance_models_)
delete model;
}
void
ReceiverModel::setCapacitanceModel(TableModel *table_model,
int index,
size_t segment,
RiseFall *rf)
{
capacitance_models_[index][rf->index()] = table_model;
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;
}
bool