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