Enable disabled liberty tests and stabilize clock groups regression
Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
This commit is contained in:
parent
2d2a275ab9
commit
a4419fb7dd
|
|
@ -46,6 +46,12 @@ static void expectStaLibertyCoreState(Sta *sta, LibertyLibrary *lib)
|
|||
EXPECT_NE(lib, nullptr);
|
||||
}
|
||||
|
||||
static LibertyAttrValue *
|
||||
makeStringAttrValue(const char *value)
|
||||
{
|
||||
return new LibertyAttrValue(std::string(value));
|
||||
}
|
||||
|
||||
class LinearModelTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
|
|
@ -1012,189 +1018,147 @@ TEST_F(StaLibertyTest, LibraryDriverWaveformDefault) {
|
|||
// R6 tests: LibertyParser classes coverage
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
TEST(R6_LibertyStmtTest, ConstructorAndVirtuals) {
|
||||
LibertyStmt *stmt = new LibertyVariable("x", 1.0f, 42);
|
||||
EXPECT_EQ(stmt->line(), 42);
|
||||
EXPECT_FALSE(stmt->isGroup());
|
||||
EXPECT_FALSE(stmt->isAttribute());
|
||||
EXPECT_FALSE(stmt->isDefine());
|
||||
EXPECT_TRUE(stmt->isVariable());
|
||||
delete stmt;
|
||||
TEST(R6_LibertyVariableTest, ConstructorAndAccessors) {
|
||||
LibertyVariable var("x", 1.0f, 42);
|
||||
EXPECT_EQ(var.line(), 42);
|
||||
EXPECT_EQ(var.variable(), "x");
|
||||
EXPECT_FLOAT_EQ(var.value(), 1.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
TEST(R6_LibertyStmtTest, LibertyStmtBaseDefaultVirtuals) {
|
||||
// LibertyStmt base class: isGroup, isAttribute, isDefine, isVariable all false
|
||||
LibertyVariable var("v", 0.0f, 1);
|
||||
LibertyStmt *base = &var;
|
||||
// LibertyVariable overrides isVariable
|
||||
EXPECT_TRUE(base->isVariable());
|
||||
EXPECT_FALSE(base->isGroup());
|
||||
EXPECT_FALSE(base->isAttribute());
|
||||
EXPECT_FALSE(base->isDefine());
|
||||
TEST(R6_LibertyAttrValueTest, FloatValueAndQuotedStringParsing) {
|
||||
LibertyAttrValue float_value(1.25f);
|
||||
EXPECT_TRUE(float_value.isFloat());
|
||||
EXPECT_FALSE(float_value.isString());
|
||||
EXPECT_FLOAT_EQ(float_value.floatValue(), 1.25f);
|
||||
|
||||
LibertyAttrValue quoted_value(std::string("3.14"));
|
||||
float parsed = 0.0f;
|
||||
bool valid = false;
|
||||
quoted_value.floatValue(parsed, valid);
|
||||
EXPECT_TRUE(valid);
|
||||
EXPECT_FLOAT_EQ(parsed, 3.14f);
|
||||
EXPECT_TRUE(quoted_value.isString());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
TEST(R6_LibertyGroupTest, Construction) {
|
||||
LibertyAttrValueSeq *params = new LibertyAttrValueSeq;
|
||||
params->push_back(new LibertyStringAttrValue("cell1"));
|
||||
LibertyGroup grp("cell", params, 10);
|
||||
EXPECT_EQ(grp.type(), "cell");
|
||||
EXPECT_TRUE(grp.isGroup());
|
||||
LibertyAttrValueSeq params;
|
||||
params.push_back(makeStringAttrValue("cell1"));
|
||||
params.push_back(makeStringAttrValue("slow"));
|
||||
LibertyGroup grp("scaled_cell", std::move(params), 10);
|
||||
EXPECT_EQ(grp.type(), "scaled_cell");
|
||||
EXPECT_EQ(grp.line(), 10);
|
||||
EXPECT_EQ(grp.firstName(), std::string("cell1"));
|
||||
ASSERT_NE(grp.firstName(), nullptr);
|
||||
EXPECT_STREQ(grp.firstName(), "cell1");
|
||||
ASSERT_NE(grp.secondName(), nullptr);
|
||||
EXPECT_STREQ(grp.secondName(), "slow");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
TEST(R6_LibertyGroupTest, AddSubgroupAndIterate) {
|
||||
LibertyAttrValueSeq *params = new LibertyAttrValueSeq;
|
||||
LibertyGroup *grp = new LibertyGroup("library", params, 1);
|
||||
LibertyAttrValueSeq *sub_params = new LibertyAttrValueSeq;
|
||||
LibertyGroup *sub = new LibertyGroup("cell", sub_params, 2);
|
||||
grp->addStmt(sub);
|
||||
LibertyStmtSeq *stmts = grp->stmts();
|
||||
ASSERT_NE(stmts, nullptr);
|
||||
EXPECT_EQ(stmts->size(), 1u);
|
||||
EXPECT_EQ((*stmts)[0], sub);
|
||||
delete grp;
|
||||
LibertyGroup grp("library", LibertyAttrValueSeq(), 1);
|
||||
auto *sub = new LibertyGroup("cell", LibertyAttrValueSeq(), 2);
|
||||
grp.addSubgroup(sub);
|
||||
EXPECT_EQ(grp.subgroups().size(), 1u);
|
||||
EXPECT_EQ(grp.subgroups()[0], sub);
|
||||
EXPECT_EQ(grp.findSubgroup("cell"), sub);
|
||||
EXPECT_EQ(grp.findSubgroups("cell").size(), 1u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
TEST(R6_LibertyGroupTest, AddAttributeAndIterate) {
|
||||
LibertyAttrValueSeq *params = new LibertyAttrValueSeq;
|
||||
LibertyGroup *grp = new LibertyGroup("cell", params, 1);
|
||||
LibertyAttrValue *val = new LibertyFloatAttrValue(3.14f);
|
||||
LibertySimpleAttr *attr = new LibertySimpleAttr("area", val, 5);
|
||||
grp->addStmt(attr);
|
||||
// Iterate over statements
|
||||
LibertyStmtSeq *stmts = grp->stmts();
|
||||
ASSERT_NE(stmts, nullptr);
|
||||
EXPECT_EQ(stmts->size(), 1u);
|
||||
EXPECT_EQ((*stmts)[0], attr);
|
||||
delete grp;
|
||||
}
|
||||
#endif
|
||||
LibertyGroup grp("cell", LibertyAttrValueSeq(), 1);
|
||||
grp.addAttr(new LibertySimpleAttr("area", LibertyAttrValue(3.14f), 5));
|
||||
const LibertySimpleAttr *attr = grp.findSimpleAttr("area");
|
||||
ASSERT_NE(attr, nullptr);
|
||||
EXPECT_EQ(attr->line(), 5);
|
||||
EXPECT_TRUE(attr->value().isFloat());
|
||||
EXPECT_FLOAT_EQ(attr->value().floatValue(), 3.14f);
|
||||
|
||||
float area = 0.0f;
|
||||
bool exists = false;
|
||||
grp.findAttrFloat("area", area, exists);
|
||||
EXPECT_TRUE(exists);
|
||||
EXPECT_FLOAT_EQ(area, 3.14f);
|
||||
}
|
||||
|
||||
#if 0
|
||||
TEST(R6_LibertySimpleAttrTest, Construction) {
|
||||
LibertyAttrValue *val = new LibertyStringAttrValue("test_value");
|
||||
LibertySimpleAttr attr("name", val, 7);
|
||||
LibertySimpleAttr attr("name", LibertyAttrValue(std::string("test_value")), 7);
|
||||
EXPECT_EQ(attr.name(), "name");
|
||||
EXPECT_TRUE(attr.isSimpleAttr());
|
||||
EXPECT_FALSE(attr.isComplexAttr());
|
||||
// isAttribute() returns false for LibertyAttr subclasses
|
||||
// (only LibertyStmt base provides it, and it returns false).
|
||||
EXPECT_FALSE(attr.isAttribute());
|
||||
LibertyAttrValue *first = attr.firstValue();
|
||||
EXPECT_NE(first, nullptr);
|
||||
EXPECT_TRUE(first->isString());
|
||||
EXPECT_EQ(first->stringValue(), "test_value");
|
||||
EXPECT_EQ(attr.line(), 7);
|
||||
ASSERT_NE(attr.stringValue(), nullptr);
|
||||
EXPECT_EQ(*attr.stringValue(), "test_value");
|
||||
EXPECT_TRUE(attr.value().isString());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
TEST(R6_LibertySimpleAttrTest, ValuesReturnsNull) {
|
||||
LibertyAttrValue *val = new LibertyFloatAttrValue(1.0f);
|
||||
LibertySimpleAttr attr("test", val, 1);
|
||||
// values() on simple attr is not standard; in implementation it triggers error
|
||||
// Just test firstValue
|
||||
EXPECT_EQ(attr.firstValue(), val);
|
||||
TEST(R6_LibertySimpleAttrTest, FloatValueStorage) {
|
||||
LibertyGroup grp("cell", LibertyAttrValueSeq(), 1);
|
||||
grp.addAttr(new LibertySimpleAttr("test", LibertyAttrValue(1.0f), 1));
|
||||
float value = 0.0f;
|
||||
bool exists = false;
|
||||
grp.findAttrFloat("test", value, exists);
|
||||
EXPECT_TRUE(exists);
|
||||
EXPECT_FLOAT_EQ(value, 1.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
TEST(R6_LibertyComplexAttrTest, Construction) {
|
||||
LibertyAttrValueSeq *vals = new LibertyAttrValueSeq;
|
||||
vals->push_back(new LibertyFloatAttrValue(1.0f));
|
||||
vals->push_back(new LibertyFloatAttrValue(2.0f));
|
||||
LibertyComplexAttr attr("values", vals, 15);
|
||||
LibertyAttrValueSeq vals;
|
||||
vals.push_back(new LibertyAttrValue(1.0f));
|
||||
vals.push_back(new LibertyAttrValue(2.0f));
|
||||
LibertyComplexAttr attr("values", std::move(vals), 15);
|
||||
EXPECT_EQ(attr.name(), "values");
|
||||
EXPECT_FALSE(attr.isSimpleAttr());
|
||||
EXPECT_TRUE(attr.isComplexAttr());
|
||||
// isAttribute() returns false for LibertyAttr subclasses
|
||||
EXPECT_FALSE(attr.isAttribute());
|
||||
LibertyAttrValue *first = attr.firstValue();
|
||||
EXPECT_EQ(attr.line(), 15);
|
||||
const LibertyAttrValue *first = attr.firstValue();
|
||||
EXPECT_NE(first, nullptr);
|
||||
EXPECT_TRUE(first->isFloat());
|
||||
EXPECT_FLOAT_EQ(first->floatValue(), 1.0f);
|
||||
LibertyAttrValueSeq *returned_vals = attr.values();
|
||||
EXPECT_EQ(returned_vals->size(), 2u);
|
||||
EXPECT_EQ(attr.values().size(), 2u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
TEST(R6_LibertyComplexAttrTest, EmptyValues) {
|
||||
LibertyAttrValueSeq *vals = new LibertyAttrValueSeq;
|
||||
LibertyComplexAttr attr("empty", vals, 1);
|
||||
LibertyAttrValue *first = attr.firstValue();
|
||||
LibertyComplexAttr attr("empty", LibertyAttrValueSeq(), 1);
|
||||
const LibertyAttrValue *first = attr.firstValue();
|
||||
EXPECT_EQ(first, nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
TEST(R6_LibertyStringAttrValueTest, Basic) {
|
||||
LibertyStringAttrValue sav("hello");
|
||||
TEST(R6_LibertyAttrValueTest, StringBasic) {
|
||||
LibertyAttrValue sav(std::string("hello"));
|
||||
EXPECT_TRUE(sav.isString());
|
||||
EXPECT_FALSE(sav.isFloat());
|
||||
EXPECT_EQ(sav.stringValue(), "hello");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
TEST(R6_LibertyFloatAttrValueTest, Basic) {
|
||||
LibertyFloatAttrValue fav(42.5f);
|
||||
TEST(R6_LibertyAttrValueTest, FloatBasic) {
|
||||
LibertyAttrValue fav(42.5f);
|
||||
EXPECT_TRUE(fav.isFloat());
|
||||
EXPECT_FALSE(fav.isString());
|
||||
EXPECT_FLOAT_EQ(fav.floatValue(), 42.5f);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
TEST(R6_LibertyDefineTest, Construction) {
|
||||
LibertyDefine def("my_attr", LibertyGroupType::cell,
|
||||
LibertyAttrType::attr_string, 20);
|
||||
EXPECT_EQ(def.name(), "my_attr");
|
||||
EXPECT_TRUE(def.isDefine());
|
||||
EXPECT_FALSE(def.isGroup());
|
||||
EXPECT_FALSE(def.isAttribute());
|
||||
EXPECT_FALSE(def.isVariable());
|
||||
EXPECT_EQ(def.groupType(), LibertyGroupType::cell);
|
||||
EXPECT_EQ(def.valueType(), LibertyAttrType::attr_string);
|
||||
EXPECT_EQ(def.line(), 20);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
TEST(R6_LibertyVariableTest, Construction) {
|
||||
LibertyVariable var("k_volt_cell_rise", 1.5f, 30);
|
||||
EXPECT_EQ(var.variable(), "k_volt_cell_rise");
|
||||
EXPECT_FLOAT_EQ(var.value(), 1.5f);
|
||||
EXPECT_TRUE(var.isVariable());
|
||||
EXPECT_FALSE(var.isGroup());
|
||||
EXPECT_FALSE(var.isDefine());
|
||||
EXPECT_EQ(var.line(), 30);
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// R6 tests: LibertyBuilder destructor
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
// LibertyBuilder default constructor removed; requires Debug*, Report*
|
||||
TEST(R6_LibertyBuilderTest, ConstructAndDestruct) {
|
||||
TEST_F(StaLibertyTest, R6_LibertyBuilderConstructAndDestruct) {
|
||||
ASSERT_NO_THROW(( [&](){
|
||||
LibertyBuilder *builder = new LibertyBuilder;
|
||||
delete builder;
|
||||
LibertyBuilder builder(sta_->debug(), sta_->report());
|
||||
(void) builder;
|
||||
|
||||
}() ));
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// R6 tests: WireloadForArea (via WireloadSelection)
|
||||
|
|
@ -1791,69 +1755,72 @@ TEST_F(StaLibertyTest, LibraryFilename) {
|
|||
|
||||
// Covers LibertyStmt::LibertyStmt(int), LibertyStmt::isVariable(),
|
||||
// LibertyGroup::isGroup(), LibertyGroup::findAttr()
|
||||
#if 0
|
||||
TEST(LibertyParserTest, LibertyGroupConstruction) {
|
||||
LibertyAttrValueSeq *params = new LibertyAttrValueSeq;
|
||||
LibertyStringAttrValue *val = new LibertyStringAttrValue("test_lib");
|
||||
params->push_back(val);
|
||||
LibertyGroup group("library", params, 1);
|
||||
EXPECT_TRUE(group.isGroup());
|
||||
EXPECT_FALSE(group.isVariable());
|
||||
LibertyGroup group("library", LibertyAttrValueSeq(), 1);
|
||||
group.addAttr(new LibertySimpleAttr("name",
|
||||
LibertyAttrValue(std::string("test_lib")),
|
||||
2));
|
||||
group.addAttr(new LibertySimpleAttr("max_cap",
|
||||
LibertyAttrValue(3.0f),
|
||||
3));
|
||||
LibertyAttrValueSeq values;
|
||||
values.push_back(new LibertyAttrValue(0.1f));
|
||||
values.push_back(new LibertyAttrValue(0.2f));
|
||||
group.addAttr(new LibertyComplexAttr("index_1", std::move(values), 4));
|
||||
group.addDefine(new LibertyDefine("my_define",
|
||||
LibertyGroupType::cell,
|
||||
LibertyAttrType::attr_string,
|
||||
5));
|
||||
group.addSubgroup(new LibertyGroup("cell", LibertyAttrValueSeq(), 6));
|
||||
|
||||
EXPECT_EQ(group.type(), "library");
|
||||
EXPECT_EQ(group.line(), 1);
|
||||
// findAttr removed from API
|
||||
ASSERT_NE(group.findAttrString("name"), nullptr);
|
||||
EXPECT_EQ(*group.findAttrString("name"), "test_lib");
|
||||
float max_cap = 0.0f;
|
||||
bool exists = false;
|
||||
group.findAttrFloat("max_cap", max_cap, exists);
|
||||
EXPECT_TRUE(exists);
|
||||
EXPECT_FLOAT_EQ(max_cap, 3.0f);
|
||||
int max_cap_int = 0;
|
||||
group.findAttrInt("max_cap", max_cap_int, exists);
|
||||
EXPECT_TRUE(exists);
|
||||
EXPECT_EQ(max_cap_int, 3);
|
||||
EXPECT_NE(group.findComplexAttr("index_1"), nullptr);
|
||||
EXPECT_EQ(group.findComplexAttrs("index_1").size(), 1u);
|
||||
EXPECT_NE(group.findSubgroup("cell"), nullptr);
|
||||
EXPECT_EQ(group.defineMap().size(), 1u);
|
||||
}
|
||||
#endif
|
||||
|
||||
// R7_LibertySimpleAttr removed (segfault)
|
||||
|
||||
// Covers LibertyComplexAttr::isSimple()
|
||||
#if 0
|
||||
TEST(LibertyParserTest, LibertyComplexAttr) {
|
||||
LibertyAttrValueSeq *vals = new LibertyAttrValueSeq;
|
||||
vals->push_back(new LibertyFloatAttrValue(1.0f));
|
||||
vals->push_back(new LibertyFloatAttrValue(2.0f));
|
||||
LibertyComplexAttr attr("complex_attr", vals, 5);
|
||||
// isAttribute() returns false for LibertyAttr subclasses
|
||||
EXPECT_FALSE(attr.isAttribute());
|
||||
EXPECT_FALSE(attr.isSimpleAttr());
|
||||
EXPECT_TRUE(attr.isComplexAttr());
|
||||
LibertyAttrValue *fv = attr.firstValue();
|
||||
LibertyAttrValueSeq vals;
|
||||
vals.push_back(makeStringAttrValue("0.1"));
|
||||
vals.push_back(new LibertyAttrValue(2.0f));
|
||||
LibertyComplexAttr attr("complex_attr", std::move(vals), 5);
|
||||
EXPECT_EQ(attr.name(), "complex_attr");
|
||||
EXPECT_EQ(attr.line(), 5);
|
||||
const LibertyAttrValue *fv = attr.firstValue();
|
||||
EXPECT_NE(fv, nullptr);
|
||||
EXPECT_TRUE(fv->isFloat());
|
||||
EXPECT_TRUE(fv->isString());
|
||||
EXPECT_EQ(fv->stringValue(), "0.1");
|
||||
EXPECT_EQ(attr.values().size(), 2u);
|
||||
}
|
||||
#endif
|
||||
|
||||
// R7_LibertyStringAttrValueFloatValue removed (segfault)
|
||||
|
||||
// R7_LibertyFloatAttrValueStringValue removed (segfault)
|
||||
|
||||
// Covers LibertyDefine::isDefine()
|
||||
#if 0
|
||||
TEST(LibertyParserTest, LibertyDefine) {
|
||||
LibertyDefine def("my_define", LibertyGroupType::cell,
|
||||
LibertyAttrType::attr_string, 20);
|
||||
EXPECT_TRUE(def.isDefine());
|
||||
EXPECT_FALSE(def.isGroup());
|
||||
EXPECT_FALSE(def.isAttribute());
|
||||
EXPECT_FALSE(def.isVariable());
|
||||
EXPECT_EQ(def.name(), "my_define");
|
||||
EXPECT_EQ(def.groupType(), LibertyGroupType::cell);
|
||||
EXPECT_EQ(def.valueType(), LibertyAttrType::attr_string);
|
||||
EXPECT_EQ(def.line(), 20);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Covers LibertyVariable::isVariable()
|
||||
#if 0
|
||||
TEST(LibertyParserTest, LibertyVariable) {
|
||||
LibertyVariable var("input_threshold_pct_rise", 50.0f, 15);
|
||||
EXPECT_TRUE(var.isVariable());
|
||||
EXPECT_FALSE(var.isGroup());
|
||||
EXPECT_FALSE(var.isAttribute());
|
||||
EXPECT_EQ(var.line(), 15);
|
||||
EXPECT_EQ(var.variable(), "input_threshold_pct_rise");
|
||||
EXPECT_FLOAT_EQ(var.value(), 50.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
// R7_LibertyGroupFindAttr removed (segfault)
|
||||
|
||||
|
|
@ -1866,14 +1833,14 @@ TEST(LibertyParserTest, LibertyVariable) {
|
|||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Covers LibertyBuilder::~LibertyBuilder()
|
||||
#if 0
|
||||
// LibertyBuilder default constructor removed; requires Debug*, Report*
|
||||
TEST(LibertyBuilderTest, LibertyBuilderDestructor) {
|
||||
LibertyBuilder *builder = new LibertyBuilder();
|
||||
TEST_F(StaLibertyTest, LibertyBuilderDestructor) {
|
||||
ASSERT_NO_THROW(( [&](){
|
||||
LibertyBuilder *builder = new LibertyBuilder(sta_->debug(), sta_->report());
|
||||
EXPECT_NE(builder, nullptr);
|
||||
delete builder;
|
||||
|
||||
}() ));
|
||||
}
|
||||
#endif
|
||||
|
||||
// R7_ToStringAllTypes removed (to_string(TimingType) not linked for liberty test target)
|
||||
|
||||
|
|
|
|||
|
|
@ -149,6 +149,66 @@ static LibertyLibrary *writeAndReadLibReturn(Sta *sta, const char *content, cons
|
|||
return lib;
|
||||
}
|
||||
|
||||
static LibertyAttrValue *
|
||||
makeStringAttrValue(const char *value)
|
||||
{
|
||||
return new LibertyAttrValue(std::string(value));
|
||||
}
|
||||
|
||||
class NoopLibertyVisitor : public LibertyGroupVisitor {
|
||||
public:
|
||||
void begin(const LibertyGroup *, LibertyGroup *) override {}
|
||||
void end(const LibertyGroup *, LibertyGroup *) override {}
|
||||
void visitAttr(const LibertySimpleAttr *) override {}
|
||||
void visitAttr(const LibertyComplexAttr *) override {}
|
||||
void visitVariable(LibertyVariable *) override {}
|
||||
};
|
||||
|
||||
class RecordingLibertyVisitor : public LibertyGroupVisitor {
|
||||
public:
|
||||
~RecordingLibertyVisitor() override
|
||||
{
|
||||
for (const LibertyGroup *group : root_groups)
|
||||
delete group;
|
||||
}
|
||||
|
||||
void begin(const LibertyGroup *group,
|
||||
LibertyGroup *parent_group) override
|
||||
{
|
||||
begin_count++;
|
||||
if (parent_group == nullptr)
|
||||
root_groups.push_back(group);
|
||||
}
|
||||
|
||||
void end(const LibertyGroup *,
|
||||
LibertyGroup *) override
|
||||
{
|
||||
end_count++;
|
||||
}
|
||||
|
||||
void visitAttr(const LibertySimpleAttr *attr) override
|
||||
{
|
||||
simple_attrs.push_back(attr);
|
||||
}
|
||||
|
||||
void visitAttr(const LibertyComplexAttr *attr) override
|
||||
{
|
||||
complex_attrs.push_back(attr);
|
||||
}
|
||||
|
||||
void visitVariable(LibertyVariable *variable) override
|
||||
{
|
||||
variables.push_back(variable);
|
||||
}
|
||||
|
||||
int begin_count = 0;
|
||||
int end_count = 0;
|
||||
std::vector<const LibertyGroup *> root_groups;
|
||||
std::vector<const LibertySimpleAttr *> simple_attrs;
|
||||
std::vector<const LibertyComplexAttr *> complex_attrs;
|
||||
std::vector<LibertyVariable *> variables;
|
||||
};
|
||||
|
||||
// ---------- Library-level default attributes ----------
|
||||
|
||||
// R9_1: default_intrinsic_rise/fall
|
||||
|
|
@ -1456,62 +1516,65 @@ TEST_F(StaLibertyTest, LeakagePowerConstruct) {
|
|||
}
|
||||
|
||||
// R9_42: LibertyGroup isGroup and isVariable
|
||||
#if 0
|
||||
TEST_F(StaLibertyTest, LibertyStmtTypes) {
|
||||
LibertyGroup grp("test", nullptr, 1);
|
||||
EXPECT_TRUE(grp.isGroup());
|
||||
EXPECT_FALSE(grp.isVariable());
|
||||
LibertyAttrValueSeq params;
|
||||
params.push_back(makeStringAttrValue("TEST"));
|
||||
LibertyGroup grp("cell", std::move(params), 1);
|
||||
EXPECT_EQ(grp.type(), "cell");
|
||||
EXPECT_EQ(grp.line(), 1);
|
||||
ASSERT_NE(grp.firstName(), nullptr);
|
||||
EXPECT_STREQ(grp.firstName(), "TEST");
|
||||
EXPECT_TRUE(grp.subgroups().empty());
|
||||
}
|
||||
#endif
|
||||
|
||||
// R9_43: LibertySimpleAttr isComplex returns false
|
||||
#if 0
|
||||
TEST_F(StaLibertyTest, LibertySimpleAttrIsComplex) {
|
||||
LibertyStringAttrValue *val = new LibertyStringAttrValue("test");
|
||||
LibertySimpleAttr attr("name", val, 1);
|
||||
EXPECT_FALSE(attr.isComplexAttr());
|
||||
// isAttribute() returns false for LibertyAttr subclasses
|
||||
EXPECT_FALSE(attr.isAttribute());
|
||||
LibertySimpleAttr attr("name", LibertyAttrValue(std::string("test")), 1);
|
||||
EXPECT_EQ(attr.name(), "name");
|
||||
EXPECT_EQ(attr.line(), 1);
|
||||
ASSERT_NE(attr.stringValue(), nullptr);
|
||||
EXPECT_EQ(*attr.stringValue(), "test");
|
||||
EXPECT_TRUE(attr.value().isString());
|
||||
}
|
||||
#endif
|
||||
|
||||
// R9_44: LibertyComplexAttr isSimple returns false
|
||||
#if 0
|
||||
TEST_F(StaLibertyTest, LibertyComplexAttrIsSimple) {
|
||||
auto *values = new LibertyAttrValueSeq;
|
||||
LibertyComplexAttr attr("name", values, 1);
|
||||
EXPECT_FALSE(attr.isSimpleAttr());
|
||||
// isAttribute() returns false for LibertyAttr subclasses
|
||||
EXPECT_FALSE(attr.isAttribute());
|
||||
LibertyAttrValueSeq values;
|
||||
values.push_back(new LibertyAttrValue(1.0f));
|
||||
values.push_back(makeStringAttrValue("2.0"));
|
||||
LibertyComplexAttr attr("name", std::move(values), 1);
|
||||
ASSERT_NE(attr.firstValue(), nullptr);
|
||||
EXPECT_TRUE(attr.firstValue()->isFloat());
|
||||
EXPECT_FLOAT_EQ(attr.firstValue()->floatValue(), 1.0f);
|
||||
EXPECT_EQ(attr.values().size(), 2u);
|
||||
}
|
||||
#endif
|
||||
|
||||
// R9_45: LibertyStringAttrValue and LibertyFloatAttrValue type checks
|
||||
#if 0
|
||||
TEST_F(StaLibertyTest, AttrValueCrossType) {
|
||||
// LibertyStringAttrValue normal usage
|
||||
LibertyStringAttrValue sval("hello");
|
||||
LibertyAttrValue sval(std::string("hello"));
|
||||
EXPECT_TRUE(sval.isString());
|
||||
EXPECT_FALSE(sval.isFloat());
|
||||
EXPECT_EQ(sval.stringValue(), "hello");
|
||||
float parsed = 0.0f;
|
||||
bool valid = true;
|
||||
sval.floatValue(parsed, valid);
|
||||
EXPECT_FALSE(valid);
|
||||
|
||||
// LibertyFloatAttrValue normal usage
|
||||
LibertyFloatAttrValue fval(3.14f);
|
||||
LibertyAttrValue fval(3.14f);
|
||||
EXPECT_FALSE(fval.isString());
|
||||
EXPECT_TRUE(fval.isFloat());
|
||||
EXPECT_FLOAT_EQ(fval.floatValue(), 3.14f);
|
||||
}
|
||||
#endif
|
||||
|
||||
// R9_46: LibertyDefine isDefine
|
||||
#if 0
|
||||
TEST_F(StaLibertyTest, LibertyDefineIsDefine) {
|
||||
LibertyDefine def("myattr", LibertyGroupType::cell,
|
||||
LibertyAttrType::attr_string, 1);
|
||||
EXPECT_TRUE(def.isDefine());
|
||||
EXPECT_FALSE(def.isVariable());
|
||||
EXPECT_EQ(def.name(), "myattr");
|
||||
EXPECT_EQ(def.groupType(), LibertyGroupType::cell);
|
||||
EXPECT_EQ(def.valueType(), LibertyAttrType::attr_string);
|
||||
EXPECT_EQ(def.line(), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
// R9_47: scaled_cell group
|
||||
TEST_F(StaLibertyTest, ScaledCell) {
|
||||
|
|
@ -1920,20 +1983,15 @@ TEST_F(StaLibertyTest, CheckTableModelCheckAxis) {
|
|||
}
|
||||
|
||||
// R9_60: TimingGroup cell/transition/constraint getter coverage
|
||||
#if 0
|
||||
TEST_F(StaLibertyTest, TimingGroupGettersNull) {
|
||||
TimingGroup tg(1);
|
||||
// By default all model pointers should be null
|
||||
EXPECT_EQ(tg.cell(RiseFall::rise()), nullptr);
|
||||
EXPECT_EQ(tg.cell(RiseFall::fall()), nullptr);
|
||||
EXPECT_EQ(tg.transition(RiseFall::rise()), nullptr);
|
||||
EXPECT_EQ(tg.transition(RiseFall::fall()), nullptr);
|
||||
EXPECT_EQ(tg.constraint(RiseFall::rise()), nullptr);
|
||||
EXPECT_EQ(tg.constraint(RiseFall::fall()), nullptr);
|
||||
EXPECT_EQ(tg.outputWaveforms(RiseFall::rise()), nullptr);
|
||||
EXPECT_EQ(tg.outputWaveforms(RiseFall::fall()), nullptr);
|
||||
TimingArcAttrs attrs;
|
||||
EXPECT_EQ(attrs.model(RiseFall::rise()), nullptr);
|
||||
EXPECT_EQ(attrs.model(RiseFall::fall()), nullptr);
|
||||
EXPECT_EQ(attrs.cond(), nullptr);
|
||||
EXPECT_TRUE(attrs.sdfCond().empty());
|
||||
EXPECT_TRUE(attrs.sdfCondStart().empty());
|
||||
EXPECT_TRUE(attrs.sdfCondEnd().empty());
|
||||
}
|
||||
#endif
|
||||
|
||||
// R9_61: Timing with ecsm_waveform_set and ecsm_capacitance
|
||||
TEST_F(StaLibertyTest, EcsmWaveformSet) {
|
||||
|
|
@ -2820,22 +2878,54 @@ library(test_r9_84) {
|
|||
}
|
||||
|
||||
// R9_85: TimingGroup makeLinearModels coverage
|
||||
#if 0
|
||||
TEST_F(StaLibertyTest, TimingGroupLinearModels) {
|
||||
TimingGroup tg(1);
|
||||
tg.setIntrinsic(RiseFall::rise(), 0.05f);
|
||||
tg.setIntrinsic(RiseFall::fall(), 0.06f);
|
||||
tg.setResistance(RiseFall::rise(), 100.0f);
|
||||
tg.setResistance(RiseFall::fall(), 120.0f);
|
||||
// makeLinearModels needs a cell - but we can verify values are set
|
||||
float val;
|
||||
bool exists;
|
||||
tg.intrinsic(RiseFall::rise(), val, exists);
|
||||
EXPECT_TRUE(exists);
|
||||
tg.resistance(RiseFall::fall(), val, exists);
|
||||
EXPECT_TRUE(exists);
|
||||
const char *content = R"(
|
||||
library(test_r9_85) {
|
||||
delay_model : generic_cmos ;
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1V" ;
|
||||
current_unit : "1mA" ;
|
||||
pulling_resistance_unit : "1kohm" ;
|
||||
capacitive_load_unit(1, ff) ;
|
||||
cell(LM2) {
|
||||
area : 2.0 ;
|
||||
pin(A) { direction : input ; capacitance : 0.01 ; }
|
||||
pin(Z) {
|
||||
direction : output ;
|
||||
function : "A" ;
|
||||
timing() {
|
||||
related_pin : "A" ;
|
||||
timing_sense : positive_unate ;
|
||||
intrinsic_rise : 0.05 ;
|
||||
intrinsic_fall : 0.06 ;
|
||||
rise_resistance : 100.0 ;
|
||||
fall_resistance : 120.0 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)";
|
||||
LibertyLibrary *lib = writeAndReadLibReturn(sta_, content);
|
||||
ASSERT_NE(lib, nullptr);
|
||||
LibertyCell *cell = lib->findLibertyCell("LM2");
|
||||
ASSERT_NE(cell, nullptr);
|
||||
|
||||
bool found_linear_model = false;
|
||||
for (TimingArcSet *arcset : cell->timingArcSets()) {
|
||||
for (TimingArc *arc : arcset->arcs()) {
|
||||
auto *model = dynamic_cast<GateLinearModel *>(arc->model());
|
||||
if (model) {
|
||||
found_linear_model = true;
|
||||
ArcDelay delay = 0.0;
|
||||
Slew slew = 0.0;
|
||||
model->gateDelay(nullptr, 0.0f, 0.5f, false, delay, slew);
|
||||
EXPECT_GT(delay, 0.0f);
|
||||
EXPECT_GE(model->driveResistance(nullptr), 100.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPECT_TRUE(found_linear_model);
|
||||
}
|
||||
#endif
|
||||
|
||||
// R9_86: multiple wire_load and default_wire_load
|
||||
TEST_F(StaLibertyTest, DefaultWireLoad) {
|
||||
|
|
@ -2963,37 +3053,54 @@ library(test_r9_89) {
|
|||
}
|
||||
|
||||
// R9_90: TimingGroup set/get cell table models
|
||||
#if 0
|
||||
TEST_F(StaLibertyTest, TimingGroupCellModels) {
|
||||
TimingGroup tg(1);
|
||||
tg.setCell(RiseFall::rise(), nullptr);
|
||||
tg.setCell(RiseFall::fall(), nullptr);
|
||||
EXPECT_EQ(tg.cell(RiseFall::rise()), nullptr);
|
||||
EXPECT_EQ(tg.cell(RiseFall::fall()), nullptr);
|
||||
LibertyCell *cell = lib_->findLibertyCell("BUF_X1");
|
||||
ASSERT_NE(cell, nullptr);
|
||||
TimingArcAttrs attrs;
|
||||
auto *rise_model = new GateLinearModel(cell, 0.01f, 10.0f);
|
||||
auto *fall_model = new GateLinearModel(cell, 0.02f, 12.0f);
|
||||
attrs.setModel(RiseFall::rise(), rise_model);
|
||||
attrs.setModel(RiseFall::fall(), fall_model);
|
||||
EXPECT_EQ(attrs.model(RiseFall::rise()), rise_model);
|
||||
EXPECT_EQ(attrs.model(RiseFall::fall()), fall_model);
|
||||
EXPECT_FLOAT_EQ(static_cast<GateLinearModel *>(attrs.model(RiseFall::rise()))
|
||||
->driveResistance(nullptr),
|
||||
10.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
// R9_91: TimingGroup constraint setters
|
||||
#if 0
|
||||
TEST_F(StaLibertyTest, TimingGroupConstraintModels) {
|
||||
TimingGroup tg(1);
|
||||
tg.setConstraint(RiseFall::rise(), nullptr);
|
||||
tg.setConstraint(RiseFall::fall(), nullptr);
|
||||
EXPECT_EQ(tg.constraint(RiseFall::rise()), nullptr);
|
||||
EXPECT_EQ(tg.constraint(RiseFall::fall()), nullptr);
|
||||
LibertyCell *cell = lib_->findLibertyCell("DFF_X1");
|
||||
ASSERT_NE(cell, nullptr);
|
||||
TimingArcAttrs attrs;
|
||||
auto *rise_model = new CheckLinearModel(cell, 0.03f);
|
||||
auto *fall_model = new CheckLinearModel(cell, 0.04f);
|
||||
attrs.setModel(RiseFall::rise(), rise_model);
|
||||
attrs.setModel(RiseFall::fall(), fall_model);
|
||||
EXPECT_EQ(attrs.model(RiseFall::rise()), rise_model);
|
||||
EXPECT_EQ(attrs.model(RiseFall::fall()), fall_model);
|
||||
EXPECT_FLOAT_EQ(static_cast<CheckLinearModel *>(attrs.model(RiseFall::fall()))
|
||||
->checkDelay(nullptr, 0.0f, 0.0f, 0.0f, false),
|
||||
0.04f);
|
||||
}
|
||||
#endif
|
||||
|
||||
// R9_92: TimingGroup transition setters
|
||||
#if 0
|
||||
TEST_F(StaLibertyTest, TimingGroupTransitionModels) {
|
||||
TimingGroup tg(1);
|
||||
tg.setTransition(RiseFall::rise(), nullptr);
|
||||
tg.setTransition(RiseFall::fall(), nullptr);
|
||||
EXPECT_EQ(tg.transition(RiseFall::rise()), nullptr);
|
||||
EXPECT_EQ(tg.transition(RiseFall::fall()), nullptr);
|
||||
LibertyCell *cell = lib_->findLibertyCell("BUF_X1");
|
||||
ASSERT_NE(cell, nullptr);
|
||||
TimingArcAttrs attrs;
|
||||
auto *rise_model = new GateLinearModel(cell, 0.05f, 7.0f);
|
||||
attrs.setModel(RiseFall::rise(), rise_model);
|
||||
ASSERT_EQ(attrs.model(RiseFall::rise()), rise_model);
|
||||
EXPECT_EQ(attrs.model(RiseFall::fall()), nullptr);
|
||||
|
||||
ArcDelay delay = 0.0;
|
||||
Slew slew = 0.0;
|
||||
static_cast<GateLinearModel *>(attrs.model(RiseFall::rise()))
|
||||
->gateDelay(nullptr, 0.0f, 0.2f, false, delay, slew);
|
||||
EXPECT_GT(delay, 0.05f);
|
||||
EXPECT_FLOAT_EQ(slew, 0.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
// R9_93: bus_naming_style attribute
|
||||
TEST_F(StaLibertyTest, BusNamingStyle) {
|
||||
|
|
@ -3397,13 +3504,21 @@ library(test_r9_104) {
|
|||
}
|
||||
|
||||
// R9_105: TimingGroup outputWaveforms accessors (should be null by default)
|
||||
#if 0
|
||||
TEST_F(StaLibertyTest, TimingGroupOutputWaveforms) {
|
||||
TimingGroup tg(1);
|
||||
EXPECT_EQ(tg.outputWaveforms(RiseFall::rise()), nullptr);
|
||||
EXPECT_EQ(tg.outputWaveforms(RiseFall::fall()), nullptr);
|
||||
LibertyCell *buf = lib_->findLibertyCell("BUF_X1");
|
||||
ASSERT_NE(buf, nullptr);
|
||||
bool found_gate_table_model = false;
|
||||
for (TimingArcSet *arcset : buf->timingArcSets()) {
|
||||
for (TimingArc *arc : arcset->arcs()) {
|
||||
auto *model = dynamic_cast<GateTableModel *>(arc->model());
|
||||
if (model) {
|
||||
found_gate_table_model = true;
|
||||
EXPECT_EQ(model->outputWaveforms(), nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPECT_TRUE(found_gate_table_model);
|
||||
}
|
||||
#endif
|
||||
|
||||
// =========================================================================
|
||||
// R11_ tests: Cover additional uncovered functions in liberty module
|
||||
|
|
@ -3448,90 +3563,67 @@ TEST_F(StaLibertyTest, WriteLiberty) {
|
|||
// LibertyAttr, LibertySimpleAttr, LibertyComplexAttr, LibertyStringAttrValue,
|
||||
// LibertyFloatAttrValue, LibertyDefine, LibertyVariable, isGroup/isAttribute/
|
||||
// isDefine/isVariable/isSimple/isComplex, and values() on simple attrs.
|
||||
#if 0
|
||||
TEST_F(StaLibertyTest, LibertyParserDirect) {
|
||||
// Write a simple lib file for parser testing
|
||||
const char *content = R"(
|
||||
library(test_r11_parser) {
|
||||
delay_model : table_lookup ;
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1V" ;
|
||||
current_unit : "1mA" ;
|
||||
capacitive_load_unit(1, ff) ;
|
||||
define(my_attr, cell, string) ;
|
||||
my_var = 3.14 ;
|
||||
cell(P1) {
|
||||
area : 1.0 ;
|
||||
pin(A) { direction : input ; capacitance : 0.01 ; }
|
||||
pin(Z) { direction : output ; function : "A" ; }
|
||||
}
|
||||
}
|
||||
)";
|
||||
std::string tmp_path = makeUniqueTmpPath();
|
||||
writeLibContent(content, tmp_path);
|
||||
RecordingLibertyVisitor visitor;
|
||||
LibertyParser parser("test_r11_parser.lib", &visitor, sta_->report());
|
||||
|
||||
// Parse with a simple visitor that just collects groups
|
||||
Report *report = sta_->report();
|
||||
// Use parseLibertyFile which creates the parser internally
|
||||
// This exercises LibertyParser constructor, LibertyScanner,
|
||||
// group(), deleteGroups()
|
||||
class TestVisitor : public LibertyGroupVisitor {
|
||||
public:
|
||||
int group_count = 0;
|
||||
int attr_count = 0;
|
||||
int var_count = 0;
|
||||
void begin(LibertyGroup *group) override { group_count++; }
|
||||
void end(LibertyGroup *) override {}
|
||||
void visitAttr(LibertyAttr *attr) override {
|
||||
attr_count++;
|
||||
// Exercise isSimple, isComplex, values()
|
||||
// isAttribute() returns false for LibertyAttr subclasses
|
||||
EXPECT_FALSE(attr->isAttribute());
|
||||
EXPECT_FALSE(attr->isGroup());
|
||||
EXPECT_FALSE(attr->isDefine());
|
||||
EXPECT_FALSE(attr->isVariable());
|
||||
if (attr->isSimpleAttr()) {
|
||||
EXPECT_FALSE(attr->isComplexAttr());
|
||||
// Simple attrs have firstValue but values() is not supported
|
||||
}
|
||||
if (attr->isComplexAttr()) {
|
||||
EXPECT_FALSE(attr->isSimpleAttr());
|
||||
}
|
||||
// Exercise firstValue
|
||||
LibertyAttrValue *val = attr->firstValue();
|
||||
if (val) {
|
||||
if (val->isString()) {
|
||||
EXPECT_FALSE(val->stringValue().empty());
|
||||
EXPECT_FALSE(val->isFloat());
|
||||
}
|
||||
if (val->isFloat()) {
|
||||
EXPECT_FALSE(val->isString());
|
||||
EXPECT_FALSE(std::isinf(val->floatValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
void visitVariable(LibertyVariable *variable) override {
|
||||
var_count++;
|
||||
EXPECT_TRUE(variable->isVariable());
|
||||
EXPECT_FALSE(variable->isGroup());
|
||||
EXPECT_FALSE(variable->isAttribute());
|
||||
EXPECT_FALSE(variable->isDefine());
|
||||
EXPECT_FALSE(variable->variable().empty());
|
||||
EXPECT_FALSE(std::isinf(variable->value()));
|
||||
}
|
||||
bool save(LibertyGroup *) override { return false; }
|
||||
bool save(LibertyAttr *) override { return false; }
|
||||
bool save(LibertyVariable *) override { return false; }
|
||||
};
|
||||
auto *lib_params = new LibertyAttrValueSeq;
|
||||
lib_params->push_back(parser.makeAttrValueString("test_r11_parser"));
|
||||
parser.groupBegin("library", lib_params, 1);
|
||||
parser.makeSimpleAttr("delay_model",
|
||||
parser.makeAttrValueString("table_lookup"),
|
||||
2);
|
||||
parser.makeSimpleAttr("time_unit",
|
||||
parser.makeAttrValueString("1ns"),
|
||||
3);
|
||||
auto *define_values = new LibertyAttrValueSeq;
|
||||
define_values->push_back(parser.makeAttrValueString("my_attr"));
|
||||
define_values->push_back(parser.makeAttrValueString("cell"));
|
||||
define_values->push_back(parser.makeAttrValueString("string"));
|
||||
parser.makeComplexAttr("define", define_values, 4);
|
||||
parser.makeVariable("my_var", 3.14f, 5);
|
||||
|
||||
TestVisitor visitor;
|
||||
parseLibertyFile(tmp_path.c_str(), &visitor, report);
|
||||
EXPECT_GT(visitor.group_count, 0);
|
||||
EXPECT_GT(visitor.attr_count, 0);
|
||||
EXPECT_GT(visitor.var_count, 0);
|
||||
remove(tmp_path.c_str());
|
||||
auto *cell_params = new LibertyAttrValueSeq;
|
||||
cell_params->push_back(parser.makeAttrValueString("P1"));
|
||||
parser.groupBegin("cell", cell_params, 6);
|
||||
parser.makeSimpleAttr("area", parser.makeAttrValueFloat(1.0f), 7);
|
||||
auto *complex_values = new LibertyAttrValueSeq;
|
||||
complex_values->push_back(parser.makeAttrValueFloat(0.01f));
|
||||
complex_values->push_back(parser.makeAttrValueFloat(0.02f));
|
||||
parser.makeComplexAttr("values", complex_values, 8);
|
||||
LibertyGroup *cell = parser.groupEnd();
|
||||
LibertyGroup *library = parser.groupEnd();
|
||||
|
||||
EXPECT_EQ(visitor.begin_count, 2);
|
||||
EXPECT_EQ(visitor.end_count, 2);
|
||||
ASSERT_EQ(visitor.root_groups.size(), 1u);
|
||||
EXPECT_EQ(visitor.root_groups.front(), library);
|
||||
EXPECT_EQ(visitor.simple_attrs.size(), 3u);
|
||||
EXPECT_EQ(visitor.complex_attrs.size(), 1u);
|
||||
EXPECT_EQ(visitor.variables.size(), 1u);
|
||||
|
||||
ASSERT_NE(library->firstName(), nullptr);
|
||||
EXPECT_STREQ(library->firstName(), "test_r11_parser");
|
||||
EXPECT_EQ(library->defineMap().size(), 1u);
|
||||
EXPECT_EQ(library->findSubgroup("cell"), cell);
|
||||
float area = 0.0f;
|
||||
bool exists = false;
|
||||
cell->findAttrFloat("area", area, exists);
|
||||
EXPECT_TRUE(exists);
|
||||
EXPECT_FLOAT_EQ(area, 1.0f);
|
||||
ASSERT_NE(cell->findComplexAttr("values"), nullptr);
|
||||
EXPECT_EQ(cell->findComplexAttr("values")->values().size(), 2u);
|
||||
EXPECT_EQ(visitor.variables[0]->variable(), "my_var");
|
||||
EXPECT_FLOAT_EQ(visitor.variables[0]->value(), 3.14f);
|
||||
|
||||
NoopLibertyVisitor cleanup_visitor;
|
||||
LibertyParser cleanup_parser("cleanup.lib", &cleanup_visitor, sta_->report());
|
||||
auto *cleanup_params = new LibertyAttrValueSeq;
|
||||
cleanup_params->push_back(cleanup_parser.makeAttrValueString("cleanup"));
|
||||
cleanup_parser.groupBegin("library", cleanup_params, 1);
|
||||
cleanup_parser.groupBegin("cell", new LibertyAttrValueSeq, 2);
|
||||
cleanup_parser.deleteGroups();
|
||||
}
|
||||
#endif
|
||||
|
||||
// R11_4: Liberty file with wireload_selection to cover WireloadForArea
|
||||
TEST_F(StaLibertyTest, WireloadForArea) {
|
||||
|
|
@ -3978,7 +4070,6 @@ library(test_r11_intport) {
|
|||
|
||||
// R11_15: Directly test LibertyParser API through parseLibertyFile
|
||||
// Focus on saving attrs/variables/groups to exercise more code paths
|
||||
#if 0
|
||||
TEST_F(StaLibertyTest, ParserSaveAll) {
|
||||
const char *content = R"(
|
||||
library(test_r11_save) {
|
||||
|
|
@ -3999,43 +4090,27 @@ library(test_r11_save) {
|
|||
std::string tmp_path = makeUniqueTmpPath();
|
||||
writeLibContent(content, tmp_path);
|
||||
|
||||
// Visitor that saves everything
|
||||
class SaveVisitor : public LibertyGroupVisitor {
|
||||
public:
|
||||
int group_begin_count = 0;
|
||||
int group_end_count = 0;
|
||||
int define_count = 0;
|
||||
int var_count = 0;
|
||||
void begin(LibertyGroup *group) override {
|
||||
group_begin_count++;
|
||||
EXPECT_TRUE(group->isGroup());
|
||||
EXPECT_FALSE(group->isAttribute());
|
||||
EXPECT_FALSE(group->isVariable());
|
||||
EXPECT_FALSE(group->isDefine());
|
||||
EXPECT_FALSE(group->type().empty());
|
||||
}
|
||||
void end(LibertyGroup *) override { group_end_count++; }
|
||||
void visitAttr(LibertyAttr *attr) override {
|
||||
// Check isDefine virtual dispatch
|
||||
if (attr->isDefine())
|
||||
define_count++;
|
||||
}
|
||||
void visitVariable(LibertyVariable *var) override {
|
||||
var_count++;
|
||||
}
|
||||
bool save(LibertyGroup *) override { return true; }
|
||||
bool save(LibertyAttr *) override { return true; }
|
||||
bool save(LibertyVariable *) override { return true; }
|
||||
};
|
||||
RecordingLibertyVisitor visitor;
|
||||
parseLibertyFile(tmp_path.c_str(), &visitor, sta_->report());
|
||||
|
||||
Report *report = sta_->report();
|
||||
SaveVisitor visitor;
|
||||
parseLibertyFile(tmp_path.c_str(), &visitor, report);
|
||||
EXPECT_GT(visitor.group_begin_count, 0);
|
||||
EXPECT_EQ(visitor.group_begin_count, visitor.group_end_count);
|
||||
remove(tmp_path.c_str());
|
||||
EXPECT_GT(visitor.begin_count, 0);
|
||||
EXPECT_EQ(visitor.begin_count, visitor.end_count);
|
||||
ASSERT_EQ(visitor.root_groups.size(), 1u);
|
||||
const LibertyGroup *library = visitor.root_groups.front();
|
||||
ASSERT_NE(library, nullptr);
|
||||
EXPECT_EQ(library->defineMap().size(), 1u);
|
||||
EXPECT_EQ(visitor.variables.size(), 1u);
|
||||
EXPECT_GT(visitor.simple_attrs.size(), 0u);
|
||||
|
||||
const LibertyGroup *cell = library->findSubgroup("cell");
|
||||
ASSERT_NE(cell, nullptr);
|
||||
float area = 0.0f;
|
||||
bool exists = false;
|
||||
cell->findAttrFloat("area", area, exists);
|
||||
EXPECT_TRUE(exists);
|
||||
EXPECT_FLOAT_EQ(area, 1.0f);
|
||||
EXPECT_EQ(remove(tmp_path.c_str()), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// R11_16: Exercises clearAxisValues and setEnergyScale through internal_power
|
||||
// with energy values
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ set_clock_uncertainty -from [get_clocks clk2] -to [get_clocks clk1] -hold 0.12
|
|||
# Write SDC with all uncertainty
|
||||
set sdc_file7 [make_result_file sdc_clk_uncert.sdc]
|
||||
write_sdc -no_timestamp $sdc_file7
|
||||
diff_files sdc_clk_uncert.sdcok $sdc_file7
|
||||
diff_files_sorted sdc_clk_uncert.sdcok $sdc_file7
|
||||
|
||||
# Remove inter-clock uncertainty
|
||||
unset_clock_uncertainty -from [get_clocks clk1] -to [get_clocks clk2] -setup
|
||||
|
|
|
|||
Loading…
Reference in New Issue