3164 lines
101 KiB
C++
3164 lines
101 KiB
C++
#include <gtest/gtest.h>
|
|
#include <string>
|
|
#include "VerilogNamespace.hh"
|
|
#include "PortDirection.hh"
|
|
#include "ConcreteLibrary.hh"
|
|
#include "ConcreteNetwork.hh"
|
|
#include "HpinDrvrLoad.hh"
|
|
#include "Network.hh"
|
|
#include "PatternMatch.hh"
|
|
#include "NetworkCmp.hh"
|
|
#include "SdcNetwork.hh"
|
|
|
|
namespace sta {
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Additional Network tests for function coverage
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// ConcreteNetwork: link and instance hierarchy tests
|
|
class ConcreteNetworkLinkedTest : public ::testing::Test {
|
|
protected:
|
|
void SetUp() override {
|
|
PortDirection::init();
|
|
// Build a simple network: top instance with 2 children
|
|
lib_ = network_.makeLibrary("test_lib", "test.lib");
|
|
Cell *inv_cell = network_.makeCell(lib_, "INV", true, "test.lib");
|
|
network_.makePort(inv_cell, "A");
|
|
network_.makePort(inv_cell, "Y");
|
|
network_.setDirection(network_.findPort(inv_cell, "A"), PortDirection::input());
|
|
network_.setDirection(network_.findPort(inv_cell, "Y"), PortDirection::output());
|
|
|
|
Cell *top_cell = network_.makeCell(lib_, "TOP", false, "test.lib");
|
|
network_.makePort(top_cell, "clk");
|
|
network_.makePort(top_cell, "data_in");
|
|
network_.makePort(top_cell, "data_out");
|
|
network_.setDirection(network_.findPort(top_cell, "clk"), PortDirection::input());
|
|
network_.setDirection(network_.findPort(top_cell, "data_in"), PortDirection::input());
|
|
network_.setDirection(network_.findPort(top_cell, "data_out"), PortDirection::output());
|
|
|
|
// Create top instance
|
|
Instance *top = network_.makeInstance(top_cell, "top", nullptr);
|
|
network_.setTopInstance(top);
|
|
|
|
// Create child instances
|
|
u1_ = network_.makeInstance(inv_cell, "u1", top);
|
|
u2_ = network_.makeInstance(inv_cell, "u2", top);
|
|
|
|
// Create nets
|
|
net1_ = network_.makeNet("n1", top);
|
|
net2_ = network_.makeNet("n2", top);
|
|
net3_ = network_.makeNet("n3", top);
|
|
|
|
// Connect pins
|
|
Port *inv_a = network_.findPort(inv_cell, "A");
|
|
Port *inv_y = network_.findPort(inv_cell, "Y");
|
|
|
|
pin_u1_a_ = network_.connect(u1_, inv_a, net1_);
|
|
pin_u1_y_ = network_.connect(u1_, inv_y, net2_);
|
|
pin_u2_a_ = network_.connect(u2_, inv_a, net2_);
|
|
pin_u2_y_ = network_.connect(u2_, inv_y, net3_);
|
|
}
|
|
|
|
void TearDown() override {
|
|
network_.clear();
|
|
}
|
|
|
|
ConcreteNetwork network_;
|
|
Library *lib_;
|
|
Instance *u1_;
|
|
Instance *u2_;
|
|
Net *net1_;
|
|
Net *net2_;
|
|
Net *net3_;
|
|
Pin *pin_u1_a_;
|
|
Pin *pin_u1_y_;
|
|
Pin *pin_u2_a_;
|
|
Pin *pin_u2_y_;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// R5_ tests for NetworkNameAdapter and SdcNetwork coverage
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// Test fixture that creates a ConcreteNetwork and wraps it with
|
|
// SdcNetwork (which extends NetworkNameAdapter) for forwarding coverage.
|
|
// NetworkNameAdapter is abstract, so we test its methods through SdcNetwork.
|
|
class NetworkAdapterTest : public ::testing::Test {
|
|
protected:
|
|
void SetUp() override {
|
|
PortDirection::init();
|
|
// Build a simple network
|
|
lib_ = network_.makeLibrary("adapter_lib", "adapter.lib");
|
|
Cell *inv_cell = network_.makeCell(lib_, "BUF", true, "adapter.lib");
|
|
port_a_ = network_.makePort(inv_cell, "A");
|
|
port_y_ = network_.makePort(inv_cell, "Y");
|
|
network_.setDirection(port_a_, PortDirection::input());
|
|
network_.setDirection(port_y_, PortDirection::output());
|
|
|
|
Cell *top_cell = network_.makeCell(lib_, "ATOP", false, "adapter.lib");
|
|
network_.makePort(top_cell, "in1");
|
|
network_.makePort(top_cell, "out1");
|
|
network_.setDirection(network_.findPort(top_cell, "in1"), PortDirection::input());
|
|
network_.setDirection(network_.findPort(top_cell, "out1"), PortDirection::output());
|
|
|
|
Instance *top = network_.makeInstance(top_cell, "atop", nullptr);
|
|
network_.setTopInstance(top);
|
|
|
|
inv_cell_ = inv_cell;
|
|
u1_ = network_.makeInstance(inv_cell, "b1", top);
|
|
net1_ = network_.makeNet("w1", top);
|
|
Port *a = network_.findPort(inv_cell, "A");
|
|
pin_b1_a_ = network_.connect(u1_, a, net1_);
|
|
|
|
// Create sdc network (extends NetworkNameAdapter, which is abstract)
|
|
sdc_net_ = new SdcNetwork(&network_);
|
|
}
|
|
|
|
void TearDown() override {
|
|
delete sdc_net_;
|
|
network_.clear();
|
|
}
|
|
|
|
ConcreteNetwork network_;
|
|
SdcNetwork *sdc_net_;
|
|
Library *lib_;
|
|
Cell *inv_cell_;
|
|
Port *port_a_;
|
|
Port *port_y_;
|
|
Instance *u1_;
|
|
Net *net1_;
|
|
Pin *pin_b1_a_;
|
|
};
|
|
|
|
// NetworkNameAdapter: topInstance forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterTopInstance) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
EXPECT_NE(top, nullptr);
|
|
EXPECT_EQ(top, network_.topInstance());
|
|
}
|
|
|
|
// NetworkNameAdapter: name(Library) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterLibraryName) {
|
|
EXPECT_STREQ(sdc_net_->name(lib_), "adapter_lib");
|
|
}
|
|
|
|
// NetworkNameAdapter: id(Library) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterLibraryId) {
|
|
ObjectId adapter_id = sdc_net_->id(lib_);
|
|
ObjectId direct_id = network_.id(lib_);
|
|
EXPECT_EQ(adapter_id, direct_id);
|
|
}
|
|
|
|
// NetworkNameAdapter: findLibrary forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterFindLibrary) {
|
|
Library *found = sdc_net_->findLibrary("adapter_lib");
|
|
EXPECT_EQ(found, lib_);
|
|
}
|
|
|
|
// NetworkNameAdapter: findLibertyFilename forwarding (no liberty libs)
|
|
TEST_F(NetworkAdapterTest, AdapterFindLibertyFilename) {
|
|
LibertyLibrary *found = sdc_net_->findLibertyFilename("nonexistent.lib");
|
|
EXPECT_EQ(found, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: findLiberty forwarding (no liberty libs)
|
|
TEST_F(NetworkAdapterTest, AdapterFindLiberty) {
|
|
LibertyLibrary *found = sdc_net_->findLiberty("nonexistent");
|
|
EXPECT_EQ(found, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: defaultLibertyLibrary forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterDefaultLibertyLibrary) {
|
|
LibertyLibrary *def = sdc_net_->defaultLibertyLibrary();
|
|
EXPECT_EQ(def, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: libraryIterator forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterLibraryIterator) {
|
|
LibraryIterator *iter = sdc_net_->libraryIterator();
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_GT(count, 0);
|
|
}
|
|
|
|
// NetworkNameAdapter: libertyLibraryIterator forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterLibertyLibraryIterator) {
|
|
LibertyLibraryIterator *iter = sdc_net_->libertyLibraryIterator();
|
|
ASSERT_NE(iter, nullptr);
|
|
// No liberty libs loaded
|
|
EXPECT_FALSE(iter->hasNext());
|
|
delete iter;
|
|
}
|
|
|
|
// NetworkNameAdapter: name(Cell) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterCellName) {
|
|
EXPECT_STREQ(sdc_net_->name(inv_cell_), "BUF");
|
|
}
|
|
|
|
// NetworkNameAdapter: id(Cell) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterCellId) {
|
|
ObjectId adapter_id = sdc_net_->id(inv_cell_);
|
|
ObjectId direct_id = network_.id(inv_cell_);
|
|
EXPECT_EQ(adapter_id, direct_id);
|
|
}
|
|
|
|
// NetworkNameAdapter: getAttribute(Cell) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterCellGetAttribute) {
|
|
std::string val = sdc_net_->getAttribute(inv_cell_, "nonexistent");
|
|
EXPECT_TRUE(val.empty());
|
|
}
|
|
|
|
// NetworkNameAdapter: attributeMap(Cell) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterCellAttributeMap) {
|
|
const AttributeMap &map = sdc_net_->attributeMap(inv_cell_);
|
|
// No attributes set, so map should be empty
|
|
EXPECT_TRUE(map.empty());
|
|
}
|
|
|
|
// NetworkNameAdapter: library(Cell) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterCellLibrary) {
|
|
Library *lib = sdc_net_->library(inv_cell_);
|
|
EXPECT_EQ(lib, lib_);
|
|
}
|
|
|
|
// NetworkNameAdapter: filename(Cell) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterCellFilename) {
|
|
const char *fn = sdc_net_->filename(inv_cell_);
|
|
EXPECT_STREQ(fn, "adapter.lib");
|
|
}
|
|
|
|
// NetworkNameAdapter: findPort forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterFindPort) {
|
|
Port *found = sdc_net_->findPort(inv_cell_, "A");
|
|
EXPECT_EQ(found, port_a_);
|
|
}
|
|
|
|
// NetworkNameAdapter: findPortsMatching forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterFindPortsMatching) {
|
|
PatternMatch pattern("*");
|
|
PortSeq ports = sdc_net_->findPortsMatching(inv_cell_, &pattern);
|
|
EXPECT_EQ(ports.size(), 2u);
|
|
}
|
|
|
|
// NetworkNameAdapter: isLeaf(Cell) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterCellIsLeaf) {
|
|
EXPECT_TRUE(sdc_net_->isLeaf(inv_cell_));
|
|
}
|
|
|
|
// NetworkNameAdapter: portIterator forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPortIterator) {
|
|
CellPortIterator *iter = sdc_net_->portIterator(inv_cell_);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 2);
|
|
}
|
|
|
|
// NetworkNameAdapter: portBitIterator forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPortBitIterator) {
|
|
CellPortBitIterator *iter = sdc_net_->portBitIterator(inv_cell_);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 2);
|
|
}
|
|
|
|
// NetworkNameAdapter: portBitCount forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPortBitCount) {
|
|
int count = sdc_net_->portBitCount(inv_cell_);
|
|
EXPECT_EQ(count, 2);
|
|
}
|
|
|
|
// NetworkNameAdapter: name(Port) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPortName) {
|
|
EXPECT_STREQ(sdc_net_->name(port_a_), "A");
|
|
}
|
|
|
|
// NetworkNameAdapter: id(Port) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPortId) {
|
|
ObjectId adapter_id = sdc_net_->id(port_a_);
|
|
ObjectId direct_id = network_.id(port_a_);
|
|
EXPECT_EQ(adapter_id, direct_id);
|
|
}
|
|
|
|
// NetworkNameAdapter: cell(Port) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPortCell) {
|
|
Cell *cell = sdc_net_->cell(port_a_);
|
|
EXPECT_EQ(cell, inv_cell_);
|
|
}
|
|
|
|
// NetworkNameAdapter: direction(Port) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPortDirection) {
|
|
PortDirection *dir = sdc_net_->direction(port_a_);
|
|
EXPECT_EQ(dir, PortDirection::input());
|
|
}
|
|
|
|
// NetworkNameAdapter: isBundle(Port) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPortIsBundle) {
|
|
EXPECT_FALSE(sdc_net_->isBundle(port_a_));
|
|
}
|
|
|
|
// NetworkNameAdapter: isBus(Port) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPortIsBus) {
|
|
EXPECT_FALSE(sdc_net_->isBus(port_a_));
|
|
}
|
|
|
|
// NetworkNameAdapter: size(Port) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPortSize) {
|
|
EXPECT_EQ(sdc_net_->size(port_a_), 1);
|
|
}
|
|
|
|
// NetworkNameAdapter: busName(Port) scalar forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPortBusName) {
|
|
const char *bn = sdc_net_->busName(port_a_);
|
|
// Scalar port returns name (not nullptr) through SdcNetwork
|
|
EXPECT_NE(bn, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: fromIndex(Port) forwarding (scalar ports return -1)
|
|
TEST_F(NetworkAdapterTest, AdapterPortFromIndex) {
|
|
int idx = sdc_net_->fromIndex(port_a_);
|
|
EXPECT_EQ(idx, -1);
|
|
}
|
|
|
|
// NetworkNameAdapter: toIndex(Port) forwarding (scalar ports return -1)
|
|
TEST_F(NetworkAdapterTest, AdapterPortToIndex) {
|
|
int idx = sdc_net_->toIndex(port_a_);
|
|
EXPECT_EQ(idx, -1);
|
|
}
|
|
|
|
// NetworkNameAdapter: hasMembers(Port) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPortHasMembers) {
|
|
EXPECT_FALSE(sdc_net_->hasMembers(port_a_));
|
|
}
|
|
|
|
// (R5_AdapterPortFindMember removed: segfaults on scalar port)
|
|
// (R5_AdapterPortFindBusBit removed: segfaults on scalar port)
|
|
|
|
// NetworkNameAdapter: id(Instance) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterInstanceId) {
|
|
ObjectId adapter_id = sdc_net_->id(u1_);
|
|
ObjectId direct_id = network_.id(u1_);
|
|
EXPECT_EQ(adapter_id, direct_id);
|
|
}
|
|
|
|
// NetworkNameAdapter: cell(Instance) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterInstanceCell) {
|
|
Cell *cell = sdc_net_->cell(u1_);
|
|
EXPECT_EQ(cell, inv_cell_);
|
|
}
|
|
|
|
// NetworkNameAdapter: getAttribute(Instance) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterInstanceGetAttribute) {
|
|
std::string val = sdc_net_->getAttribute(u1_, "nonexistent");
|
|
EXPECT_TRUE(val.empty());
|
|
}
|
|
|
|
// NetworkNameAdapter: attributeMap(Instance) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterInstanceAttributeMap) {
|
|
const AttributeMap &map = sdc_net_->attributeMap(u1_);
|
|
// No attributes set, so map should be empty
|
|
EXPECT_TRUE(map.empty());
|
|
}
|
|
|
|
// NetworkNameAdapter: parent(Instance) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterInstanceParent) {
|
|
Instance *parent = sdc_net_->parent(u1_);
|
|
EXPECT_EQ(parent, network_.topInstance());
|
|
}
|
|
|
|
// NetworkNameAdapter: isLeaf(Instance) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterInstanceIsLeaf) {
|
|
EXPECT_TRUE(sdc_net_->isLeaf(u1_));
|
|
}
|
|
|
|
// NetworkNameAdapter: findPin(Instance, Port) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterFindPinByPort) {
|
|
Pin *pin = sdc_net_->findPin(u1_, port_a_);
|
|
EXPECT_EQ(pin, pin_b1_a_);
|
|
}
|
|
|
|
// (R5_AdapterFindPinByLibertyPort removed: segfaults with nullptr LibertyPort)
|
|
|
|
// NetworkNameAdapter: childIterator forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterChildIterator) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
InstanceChildIterator *iter = sdc_net_->childIterator(top);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 1);
|
|
}
|
|
|
|
// NetworkNameAdapter: pinIterator(Instance) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterInstancePinIterator) {
|
|
InstancePinIterator *iter = sdc_net_->pinIterator(u1_);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_GE(count, 1);
|
|
}
|
|
|
|
// NetworkNameAdapter: netIterator(Instance) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterInstanceNetIterator) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
InstanceNetIterator *iter = sdc_net_->netIterator(top);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_GE(count, 1);
|
|
}
|
|
|
|
// NetworkNameAdapter: id(Pin) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPinId) {
|
|
ObjectId adapter_id = sdc_net_->id(pin_b1_a_);
|
|
ObjectId direct_id = network_.id(pin_b1_a_);
|
|
EXPECT_EQ(adapter_id, direct_id);
|
|
}
|
|
|
|
// NetworkNameAdapter: port(Pin) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPinPort) {
|
|
Port *port = sdc_net_->port(pin_b1_a_);
|
|
EXPECT_EQ(port, port_a_);
|
|
}
|
|
|
|
// NetworkNameAdapter: instance(Pin) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPinInstance) {
|
|
Instance *inst = sdc_net_->instance(pin_b1_a_);
|
|
EXPECT_EQ(inst, u1_);
|
|
}
|
|
|
|
// NetworkNameAdapter: net(Pin) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPinNet) {
|
|
Net *net = sdc_net_->net(pin_b1_a_);
|
|
EXPECT_EQ(net, net1_);
|
|
}
|
|
|
|
// NetworkNameAdapter: term(Pin) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPinTerm) {
|
|
Term *term = sdc_net_->term(pin_b1_a_);
|
|
// leaf instance pins have no term
|
|
EXPECT_EQ(term, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: direction(Pin) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPinDirection) {
|
|
PortDirection *dir = sdc_net_->direction(pin_b1_a_);
|
|
EXPECT_EQ(dir, PortDirection::input());
|
|
}
|
|
|
|
// NetworkNameAdapter: vertexId(Pin) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPinVertexId) {
|
|
VertexId vid = sdc_net_->vertexId(pin_b1_a_);
|
|
// VertexId is a valid value (could be 0 for unset)
|
|
EXPECT_GE(vid, 0u);
|
|
}
|
|
|
|
// NetworkNameAdapter: setVertexId forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterSetVertexId) {
|
|
sdc_net_->setVertexId(pin_b1_a_, 42);
|
|
VertexId vid = sdc_net_->vertexId(pin_b1_a_);
|
|
EXPECT_EQ(vid, 42u);
|
|
}
|
|
|
|
// NetworkNameAdapter: id(Net) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterNetId) {
|
|
ObjectId adapter_id = sdc_net_->id(net1_);
|
|
ObjectId direct_id = network_.id(net1_);
|
|
EXPECT_EQ(adapter_id, direct_id);
|
|
}
|
|
|
|
// NetworkNameAdapter: instance(Net) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterNetInstance) {
|
|
Instance *inst = sdc_net_->instance(net1_);
|
|
EXPECT_EQ(inst, network_.topInstance());
|
|
}
|
|
|
|
// NetworkNameAdapter: isPower(Net) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterNetIsPower) {
|
|
EXPECT_FALSE(sdc_net_->isPower(net1_));
|
|
}
|
|
|
|
// NetworkNameAdapter: isGround(Net) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterNetIsGround) {
|
|
EXPECT_FALSE(sdc_net_->isGround(net1_));
|
|
}
|
|
|
|
// NetworkNameAdapter: pinIterator(Net) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterNetPinIterator) {
|
|
NetPinIterator *iter = sdc_net_->pinIterator(net1_);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_GE(count, 1);
|
|
}
|
|
|
|
// NetworkNameAdapter: termIterator(Net) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterNetTermIterator) {
|
|
NetTermIterator *iter = sdc_net_->termIterator(net1_);
|
|
ASSERT_NE(iter, nullptr);
|
|
delete iter;
|
|
}
|
|
|
|
// NetworkNameAdapter: constantPinIterator forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterConstantPinIterator) {
|
|
ConstantPinIterator *iter = sdc_net_->constantPinIterator();
|
|
ASSERT_NE(iter, nullptr);
|
|
delete iter;
|
|
}
|
|
|
|
// NetworkNameAdapter: pathDivider forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPathDivider) {
|
|
char div = sdc_net_->pathDivider();
|
|
EXPECT_EQ(div, network_.pathDivider());
|
|
}
|
|
|
|
// NetworkNameAdapter: setPathDivider forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterSetPathDivider) {
|
|
sdc_net_->setPathDivider('/');
|
|
EXPECT_EQ(network_.pathDivider(), '/');
|
|
}
|
|
|
|
// NetworkNameAdapter: pathEscape forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPathEscape) {
|
|
char esc = sdc_net_->pathEscape();
|
|
EXPECT_EQ(esc, network_.pathEscape());
|
|
}
|
|
|
|
// NetworkNameAdapter: setPathEscape forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterSetPathEscape) {
|
|
sdc_net_->setPathEscape('~');
|
|
EXPECT_EQ(network_.pathEscape(), '~');
|
|
}
|
|
|
|
// NetworkNameAdapter: isEditable forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterIsEditable) {
|
|
EXPECT_TRUE(sdc_net_->isEditable());
|
|
}
|
|
|
|
// NetworkNameAdapter: libertyCell(Cell) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterLibertyCellFromCell) {
|
|
LibertyCell *lc = sdc_net_->libertyCell(inv_cell_);
|
|
EXPECT_EQ(lc, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: libertyCell(const Cell) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterConstLibertyCellFromCell) {
|
|
const LibertyCell *lc = sdc_net_->libertyCell(static_cast<const Cell*>(inv_cell_));
|
|
EXPECT_EQ(lc, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: cell(LibertyCell*) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterCellFromLibertyCell) {
|
|
Cell *c = sdc_net_->cell(static_cast<LibertyCell*>(nullptr));
|
|
EXPECT_EQ(c, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: cell(const LibertyCell*) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterCellFromConstLibertyCell) {
|
|
const Cell *c = sdc_net_->cell(static_cast<const LibertyCell*>(nullptr));
|
|
EXPECT_EQ(c, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: mergedInto forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterMergedInto) {
|
|
Net *merged = sdc_net_->mergedInto(net1_);
|
|
EXPECT_EQ(merged, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: makeNet forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterMakeNet) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Net *new_net = sdc_net_->makeNet("adapter_net", top);
|
|
EXPECT_NE(new_net, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: connect(Instance, Port, Net) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterConnect) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Net *new_net = sdc_net_->makeNet("connect_net", top);
|
|
Pin *pin = sdc_net_->connect(u1_, port_y_, new_net);
|
|
EXPECT_NE(pin, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: disconnectPin forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterDisconnectPin) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Net *new_net = sdc_net_->makeNet("disc_net", top);
|
|
Pin *pin = sdc_net_->connect(u1_, port_y_, new_net);
|
|
ASSERT_NE(pin, nullptr);
|
|
sdc_net_->disconnectPin(pin);
|
|
// After disconnect, net(pin) should be nullptr
|
|
EXPECT_EQ(sdc_net_->net(pin), nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: deletePin forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterDeletePin) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Net *new_net = sdc_net_->makeNet("delpin_net", top);
|
|
Pin *pin = sdc_net_->connect(u1_, port_y_, new_net);
|
|
ASSERT_NE(pin, nullptr);
|
|
sdc_net_->disconnectPin(pin);
|
|
sdc_net_->deletePin(pin);
|
|
// Just verify it doesn't crash
|
|
}
|
|
|
|
// NetworkNameAdapter: mergeInto forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterMergeInto) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Net *net_a = sdc_net_->makeNet("merge_a", top);
|
|
Net *net_b = sdc_net_->makeNet("merge_b", top);
|
|
sdc_net_->mergeInto(net_a, net_b);
|
|
Net *merged = sdc_net_->mergedInto(net_a);
|
|
EXPECT_EQ(merged, net_b);
|
|
}
|
|
|
|
// SdcNetwork: constructor and basic forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkTopInstance) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
EXPECT_NE(top, nullptr);
|
|
EXPECT_EQ(top, network_.topInstance());
|
|
}
|
|
|
|
// SdcNetwork: name(Port) forwarding with sdc namespace
|
|
TEST_F(NetworkAdapterTest, SdcNetworkPortName) {
|
|
const char *name = sdc_net_->name(port_a_);
|
|
EXPECT_NE(name, nullptr);
|
|
}
|
|
|
|
// SdcNetwork: busName(Port) forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkPortBusName) {
|
|
const char *bn = sdc_net_->busName(port_a_);
|
|
// SdcNetwork busName returns name for scalar port
|
|
EXPECT_NE(bn, nullptr);
|
|
}
|
|
|
|
// SdcNetwork: findPort forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkFindPort) {
|
|
Port *found = sdc_net_->findPort(inv_cell_, "A");
|
|
EXPECT_EQ(found, port_a_);
|
|
}
|
|
|
|
// SdcNetwork: findPortsMatching forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkFindPortsMatching) {
|
|
PatternMatch pattern("*");
|
|
PortSeq ports = sdc_net_->findPortsMatching(inv_cell_, &pattern);
|
|
EXPECT_EQ(ports.size(), 2u);
|
|
}
|
|
|
|
// SdcNetwork: findNet(Instance, name) forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkFindNet) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Net *found = sdc_net_->findNet(top, "w1");
|
|
EXPECT_EQ(found, net1_);
|
|
}
|
|
|
|
// SdcNetwork: name(Instance) forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkInstanceName) {
|
|
const char *name = sdc_net_->name(u1_);
|
|
EXPECT_NE(name, nullptr);
|
|
}
|
|
|
|
// SdcNetwork: pathName(Instance) forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkInstancePathName) {
|
|
const char *path = sdc_net_->pathName(u1_);
|
|
EXPECT_NE(path, nullptr);
|
|
}
|
|
|
|
// SdcNetwork: pathName(Pin) forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkPinPathName) {
|
|
const char *path = sdc_net_->pathName(pin_b1_a_);
|
|
EXPECT_NE(path, nullptr);
|
|
}
|
|
|
|
// SdcNetwork: portName(Pin) forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkPinPortName) {
|
|
const char *port_name = sdc_net_->portName(pin_b1_a_);
|
|
EXPECT_NE(port_name, nullptr);
|
|
}
|
|
|
|
// SdcNetwork: name(Net) forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkNetName) {
|
|
const char *name = sdc_net_->name(net1_);
|
|
EXPECT_NE(name, nullptr);
|
|
}
|
|
|
|
// SdcNetwork: pathName(Net) forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkNetPathName) {
|
|
const char *path = sdc_net_->pathName(net1_);
|
|
EXPECT_NE(path, nullptr);
|
|
}
|
|
|
|
// SdcNetwork: findChild forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkFindChild) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Instance *child = sdc_net_->findChild(top, "b1");
|
|
EXPECT_EQ(child, u1_);
|
|
}
|
|
|
|
// SdcNetwork: findInstance by path name
|
|
TEST_F(NetworkAdapterTest, SdcNetworkFindInstance) {
|
|
Instance *found = sdc_net_->findInstance("b1");
|
|
EXPECT_EQ(found, u1_);
|
|
}
|
|
|
|
// SdcNetwork: findPin(path) forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkFindPinPath) {
|
|
Pin *found = sdc_net_->findPin("b1/A");
|
|
EXPECT_EQ(found, pin_b1_a_);
|
|
}
|
|
|
|
// SdcNetwork: findPin(Instance, port_name) forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkFindPinInstancePort) {
|
|
Pin *found = sdc_net_->findPin(u1_, "A");
|
|
EXPECT_EQ(found, pin_b1_a_);
|
|
}
|
|
|
|
// SdcNetwork: findNet(path) forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkFindNetPath) {
|
|
Net *found = sdc_net_->findNet("w1");
|
|
EXPECT_EQ(found, net1_);
|
|
}
|
|
|
|
// SdcNetwork: findNetRelative forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkFindNetRelative) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Net *found = sdc_net_->findNetRelative(top, "w1");
|
|
EXPECT_EQ(found, net1_);
|
|
}
|
|
|
|
// SdcNetwork: findNetsMatching forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkFindNetsMatching) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
PatternMatch pattern("w*");
|
|
NetSeq nets = sdc_net_->findNetsMatching(top, &pattern);
|
|
EXPECT_GE(nets.size(), 1u);
|
|
}
|
|
|
|
// SdcNetwork: findInstNetsMatching forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkFindInstNetsMatching) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
PatternMatch pattern("w*");
|
|
NetSeq nets;
|
|
sdc_net_->findInstNetsMatching(top, &pattern, nets);
|
|
EXPECT_GE(nets.size(), 1u);
|
|
}
|
|
|
|
// SdcNetwork: findInstancesMatching forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkFindInstancesMatching) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
PatternMatch pattern("b*");
|
|
InstanceSeq insts = sdc_net_->findInstancesMatching(top, &pattern);
|
|
EXPECT_GE(insts.size(), 1u);
|
|
}
|
|
|
|
// SdcNetwork: findPinsMatching forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkFindPinsMatching) {
|
|
PatternMatch pattern("b1/A");
|
|
PinSeq pins = sdc_net_->findPinsMatching(network_.topInstance(), &pattern);
|
|
EXPECT_GE(pins.size(), 1u);
|
|
}
|
|
|
|
// SdcNetwork: findInstanceRelative forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkFindInstanceRelative) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Instance *found = sdc_net_->findInstanceRelative(top, "b1");
|
|
EXPECT_EQ(found, u1_);
|
|
}
|
|
|
|
// SdcNetwork: makeNet forwarding
|
|
TEST_F(NetworkAdapterTest, SdcNetworkMakeNet) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Net *new_net = sdc_net_->makeNet("sdc_net_new", top);
|
|
EXPECT_NE(new_net, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: location forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterLocation) {
|
|
double x, y;
|
|
bool exists;
|
|
sdc_net_->location(pin_b1_a_, x, y, exists);
|
|
EXPECT_FALSE(exists);
|
|
}
|
|
|
|
// NetworkNameAdapter: libertyPort forwarding (non-liberty port)
|
|
TEST_F(NetworkAdapterTest, AdapterLibertyPort) {
|
|
LibertyPort *lp = sdc_net_->libertyPort(port_a_);
|
|
EXPECT_EQ(lp, nullptr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// R6_ tests for additional network coverage
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// ConcreteNetwork: addConstantNet then verify iteration
|
|
TEST_F(ConcreteNetworkLinkedTest, AddConstantAndIterate) {
|
|
network_.addConstantNet(net1_, LogicValue::one);
|
|
ConstantPinIterator *iter = network_.constantPinIterator();
|
|
EXPECT_NE(iter, nullptr);
|
|
bool found = false;
|
|
while (iter->hasNext()) {
|
|
const Pin *pin;
|
|
LogicValue val;
|
|
iter->next(pin, val);
|
|
if (val == LogicValue::one)
|
|
found = true;
|
|
}
|
|
delete iter;
|
|
EXPECT_TRUE(found);
|
|
}
|
|
|
|
// ConcreteInstance: cell() accessor
|
|
TEST_F(ConcreteNetworkLinkedTest, ConcreteInstanceCell) {
|
|
Cell *cell = network_.cell(u1_);
|
|
EXPECT_NE(cell, nullptr);
|
|
EXPECT_STREQ(network_.name(cell), "INV");
|
|
}
|
|
|
|
// ConcreteInstance: findChild returns nullptr on leaf
|
|
TEST_F(ConcreteNetworkLinkedTest, FindChildOnLeaf) {
|
|
// u1_ is a leaf instance, should have no children
|
|
Instance *child = network_.findChild(u1_, "nonexistent");
|
|
EXPECT_EQ(child, nullptr);
|
|
}
|
|
|
|
// ConcreteInstance: findPin(Port) with existing port
|
|
TEST_F(ConcreteNetworkLinkedTest, FindPinByPortDirect) {
|
|
Cell *cell = network_.cell(u1_);
|
|
Port *port_a = network_.findPort(cell, "A");
|
|
Pin *pin = network_.findPin(u1_, port_a);
|
|
EXPECT_EQ(pin, pin_u1_a_);
|
|
}
|
|
|
|
// ConcreteInstance: deleteChild
|
|
TEST_F(ConcreteNetworkLinkedTest, DeleteChild) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *top = network_.topInstance();
|
|
Instance *temp = network_.makeInstance(inv_cell, "temp_child", top);
|
|
EXPECT_NE(network_.findChild(top, "temp_child"), nullptr);
|
|
// Need to delete the instance properly through the network
|
|
network_.deleteInstance(temp);
|
|
EXPECT_EQ(network_.findChild(top, "temp_child"), nullptr);
|
|
}
|
|
|
|
// ConcreteInstance: addNet and deleteNet (via network)
|
|
TEST_F(ConcreteNetworkLinkedTest, AddAndDeleteNet) {
|
|
Instance *top = network_.topInstance();
|
|
Net *new_net = network_.makeNet("r6_net", top);
|
|
EXPECT_NE(new_net, nullptr);
|
|
EXPECT_NE(network_.findNet(top, "r6_net"), nullptr);
|
|
network_.deleteNet(new_net);
|
|
EXPECT_EQ(network_.findNet(top, "r6_net"), nullptr);
|
|
}
|
|
|
|
// ConcreteInstance: setCell (replaceCell exercises setCell)
|
|
TEST_F(ConcreteNetworkLinkedTest, SetCellViaReplace) {
|
|
Cell *buf_cell = network_.makeCell(lib_, "BUF_R6", true, "test.lib");
|
|
network_.makePort(buf_cell, "A");
|
|
network_.makePort(buf_cell, "Y");
|
|
network_.setDirection(network_.findPort(buf_cell, "A"), PortDirection::input());
|
|
network_.setDirection(network_.findPort(buf_cell, "Y"), PortDirection::output());
|
|
|
|
// Disconnect pins before replacing cell
|
|
network_.disconnectPin(pin_u1_a_);
|
|
network_.disconnectPin(pin_u1_y_);
|
|
network_.replaceCell(u1_, buf_cell);
|
|
Cell *new_cell = network_.cell(u1_);
|
|
EXPECT_STREQ(network_.name(new_cell), "BUF_R6");
|
|
}
|
|
|
|
// ConcretePin: name() via Network base class
|
|
TEST_F(ConcreteNetworkLinkedTest, ConcretePinName) {
|
|
const Network &net = network_;
|
|
const char *name = net.name(pin_u1_a_);
|
|
EXPECT_NE(name, nullptr);
|
|
// Pin name is instance/port
|
|
std::string name_str(name);
|
|
EXPECT_NE(name_str.find("A"), std::string::npos);
|
|
}
|
|
|
|
// ConcretePin: setVertexId
|
|
TEST_F(ConcreteNetworkLinkedTest, PinSetVertexIdMultiple) {
|
|
network_.setVertexId(pin_u1_a_, 100);
|
|
EXPECT_EQ(network_.vertexId(pin_u1_a_), 100u);
|
|
network_.setVertexId(pin_u1_a_, 200);
|
|
EXPECT_EQ(network_.vertexId(pin_u1_a_), 200u);
|
|
network_.setVertexId(pin_u1_a_, 0);
|
|
EXPECT_EQ(network_.vertexId(pin_u1_a_), 0u);
|
|
}
|
|
|
|
// ConcreteTerm: name() via Network base class
|
|
TEST_F(ConcreteNetworkLinkedTest, ConcreteTermName) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *u3 = network_.makeInstance(inv_cell, "u3_term", network_.topInstance());
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Net *net = network_.makeNet("term_net", network_.topInstance());
|
|
Pin *pin = network_.makePin(u3, port_a, net);
|
|
Term *term = network_.makeTerm(pin, net);
|
|
EXPECT_NE(term, nullptr);
|
|
const Network &base_net = network_;
|
|
const char *tname = base_net.name(term);
|
|
EXPECT_NE(tname, nullptr);
|
|
}
|
|
|
|
// Network: name(Term), pathName(Term), portName(Term)
|
|
TEST_F(ConcreteNetworkLinkedTest, TermPathAndPortName) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *u4 = network_.makeInstance(inv_cell, "u4_term", network_.topInstance());
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Net *net = network_.makeNet("term_net2", network_.topInstance());
|
|
Pin *pin = network_.makePin(u4, port_a, net);
|
|
Term *term = network_.makeTerm(pin, net);
|
|
EXPECT_NE(term, nullptr);
|
|
|
|
const Network &base_net = network_;
|
|
const char *tname = base_net.name(term);
|
|
EXPECT_NE(tname, nullptr);
|
|
|
|
const char *tpath = base_net.pathName(term);
|
|
EXPECT_NE(tpath, nullptr);
|
|
|
|
const char *tport = base_net.portName(term);
|
|
EXPECT_NE(tport, nullptr);
|
|
}
|
|
|
|
// Network: id(Term)
|
|
TEST_F(ConcreteNetworkLinkedTest, TermId2) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *u5 = network_.makeInstance(inv_cell, "u5_term", network_.topInstance());
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Net *net = network_.makeNet("term_net3", network_.topInstance());
|
|
Pin *pin = network_.makePin(u5, port_a, net);
|
|
Term *term = network_.makeTerm(pin, net);
|
|
ObjectId id = network_.id(term);
|
|
EXPECT_GE(id, 0u);
|
|
}
|
|
|
|
// Network: findPin by string name on instance
|
|
TEST_F(ConcreteNetworkLinkedTest, FindPinByStringName) {
|
|
Pin *found = network_.findPin(u1_, "A");
|
|
EXPECT_EQ(found, pin_u1_a_);
|
|
Pin *found_y = network_.findPin(u1_, "Y");
|
|
EXPECT_EQ(found_y, pin_u1_y_);
|
|
Pin *notfound = network_.findPin(u1_, "nonexistent");
|
|
EXPECT_EQ(notfound, nullptr);
|
|
}
|
|
|
|
// Network: findNet by instance and name
|
|
TEST_F(ConcreteNetworkLinkedTest, FindNetByInstanceName) {
|
|
Instance *top = network_.topInstance();
|
|
Net *found = network_.findNet(top, "n1");
|
|
EXPECT_EQ(found, net1_);
|
|
Net *found2 = network_.findNet(top, "n2");
|
|
EXPECT_EQ(found2, net2_);
|
|
Net *notfound = network_.findNet(top, "nonexistent");
|
|
EXPECT_EQ(notfound, nullptr);
|
|
}
|
|
|
|
// Network: findNetsMatching comprehensive
|
|
TEST_F(ConcreteNetworkLinkedTest, FindNetsMatchingComprehensive) {
|
|
Instance *top = network_.topInstance();
|
|
PatternMatch pattern_all("*");
|
|
NetSeq all_matches = network_.findNetsMatching(top, &pattern_all);
|
|
EXPECT_GE(all_matches.size(), 3u);
|
|
}
|
|
|
|
// Network: hasMembersOnScalarPort
|
|
TEST_F(ConcreteNetworkLinkedTest, HasMembersScalar) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
EXPECT_FALSE(network_.hasMembers(port_a));
|
|
}
|
|
|
|
// Network: hasMembersOnBusPort
|
|
TEST_F(ConcreteNetworkLinkedTest, HasMembersBusPort) {
|
|
ConcreteLibrary *clib = reinterpret_cast<ConcreteLibrary*>(lib_);
|
|
clib->setBusBrkts('[', ']');
|
|
Cell *cell = network_.makeCell(lib_, "R6_BUS_TEST", true, "test.lib");
|
|
Port *bus = network_.makeBusPort(cell, "D", 3, 0);
|
|
EXPECT_TRUE(network_.hasMembers(bus));
|
|
}
|
|
|
|
// Network: libertyCell from const cell
|
|
TEST_F(ConcreteNetworkLinkedTest, LibertyCellFromConstCell) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
const Cell *cc = inv_cell;
|
|
const LibertyCell *lcell = network_.libertyCell(cc);
|
|
EXPECT_EQ(lcell, nullptr);
|
|
}
|
|
|
|
// ConcreteNet: destructor (via deleteNet which calls ~ConcreteNet)
|
|
TEST_F(ConcreteNetworkLinkedTest, NetDestructor) {
|
|
Instance *top = network_.topInstance();
|
|
Net *temp_net = network_.makeNet("r6_temp_net", top);
|
|
EXPECT_NE(network_.findNet(top, "r6_temp_net"), nullptr);
|
|
network_.deleteNet(temp_net);
|
|
EXPECT_EQ(network_.findNet(top, "r6_temp_net"), nullptr);
|
|
}
|
|
|
|
// ConcreteNet: addPin, addTerm via connect and makeTerm
|
|
TEST_F(ConcreteNetworkLinkedTest, NetAddPinAndTerm) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *u6 = network_.makeInstance(inv_cell, "u6", network_.topInstance());
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Net *net = network_.makeNet("r6_connect_net", network_.topInstance());
|
|
|
|
// connect adds pin to net
|
|
Pin *pin = network_.connect(u6, port_a, net);
|
|
EXPECT_NE(pin, nullptr);
|
|
EXPECT_EQ(network_.net(pin), net);
|
|
|
|
// makeTerm adds term to net
|
|
Term *term = network_.makeTerm(pin, net);
|
|
EXPECT_NE(term, nullptr);
|
|
}
|
|
|
|
// ConcreteNet: deleteTerm (via disconnect which removes term)
|
|
TEST_F(ConcreteNetworkLinkedTest, NetTermIteratorAfterConnect) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *u7 = network_.makeInstance(inv_cell, "u7", network_.topInstance());
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Net *net = network_.makeNet("r6_term_iter_net", network_.topInstance());
|
|
Pin *pin = network_.makePin(u7, port_a, net);
|
|
Term *term = network_.makeTerm(pin, net);
|
|
EXPECT_NE(term, nullptr);
|
|
|
|
// Iterate terms
|
|
NetTermIterator *iter = network_.termIterator(net);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_GE(count, 1);
|
|
}
|
|
|
|
// ConcreteInstancePinIterator constructor exercise
|
|
TEST_F(ConcreteNetworkLinkedTest, InstancePinIteratorExercise) {
|
|
InstancePinIterator *iter = network_.pinIterator(u1_);
|
|
ASSERT_NE(iter, nullptr);
|
|
PinSeq pins;
|
|
while (iter->hasNext()) {
|
|
pins.push_back(iter->next());
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(pins.size(), 2u);
|
|
}
|
|
|
|
// ConcreteNetPinIterator constructor
|
|
TEST_F(ConcreteNetworkLinkedTest, NetPinIteratorExercise) {
|
|
// net1_ has 1 pin (u1_A)
|
|
NetPinIterator *iter = network_.pinIterator(net1_);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 1);
|
|
}
|
|
|
|
// ConcreteNetTermIterator
|
|
TEST_F(ConcreteNetworkLinkedTest, NetTermIteratorEmpty) {
|
|
// net3_ has pins but no terms (leaf connections)
|
|
NetTermIterator *iter = network_.termIterator(net3_);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_GE(count, 0);
|
|
}
|
|
|
|
// ConcreteLibertyLibraryIterator (exercises constructor and destructor)
|
|
TEST(ConcreteNetworkExtraTest, LibertyLibIteratorEmpty) {
|
|
ConcreteNetwork network;
|
|
LibertyLibraryIterator *iter = network.libertyLibraryIterator();
|
|
ASSERT_NE(iter, nullptr);
|
|
EXPECT_FALSE(iter->hasNext());
|
|
delete iter;
|
|
}
|
|
|
|
// ConcreteLibertyLibraryIterator with one liberty library
|
|
TEST(ConcreteNetworkExtraTest, LibertyLibIteratorWithLib) {
|
|
ConcreteNetwork network;
|
|
network.makeLibertyLibrary("r6_lib", "r6.lib");
|
|
LibertyLibraryIterator *iter = network.libertyLibraryIterator();
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 1);
|
|
}
|
|
|
|
// ConcreteLibraryIterator1 (exercises constructor)
|
|
TEST(ConcreteNetworkExtraTest, LibraryIteratorMultiple) {
|
|
ConcreteNetwork network;
|
|
network.makeLibrary("r6_lib1", "r6_1.lib");
|
|
network.makeLibrary("r6_lib2", "r6_2.lib");
|
|
network.makeLibrary("r6_lib3", "r6_3.lib");
|
|
LibraryIterator *iter = network.libraryIterator();
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 3);
|
|
}
|
|
|
|
// ConcreteCellPortIterator1 (exercises constructor)
|
|
TEST(ConcreteCellTest, PortIterator1) {
|
|
ConcreteLibrary lib("test_lib", "test.lib", false);
|
|
ConcreteCell *cell = lib.makeCell("R6_AND3", true, "");
|
|
cell->makePort("A");
|
|
cell->makePort("B");
|
|
cell->makePort("C");
|
|
cell->makePort("Y");
|
|
|
|
ConcreteCellPortIterator *iter = cell->portIterator();
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 4);
|
|
}
|
|
|
|
// ConcreteCellPortBitIterator (with bus ports)
|
|
TEST(ConcreteCellTest, PortBitIteratorWithBus) {
|
|
ConcreteLibrary lib("test_lib", "test.lib", false);
|
|
lib.setBusBrkts('[', ']');
|
|
ConcreteCell *cell = lib.makeCell("R6_REG8", true, "");
|
|
cell->makePort("CLK");
|
|
cell->makeBusPort("D", 7, 0); // 8-bit bus
|
|
cell->makePort("RST");
|
|
|
|
ConcreteCellPortBitIterator *iter = cell->portBitIterator();
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
// CLK(1) + D[0..7](8) + RST(1) = 10
|
|
EXPECT_EQ(count, 10);
|
|
}
|
|
|
|
// ConcreteCellPortBitIterator1 exercise
|
|
TEST(ConcreteCellTest, PortBitIterator1Simple) {
|
|
ConcreteLibrary lib("test_lib", "test.lib", false);
|
|
ConcreteCell *cell = lib.makeCell("R6_INV2", true, "");
|
|
cell->makePort("A");
|
|
cell->makePort("Y");
|
|
|
|
ConcreteCellPortBitIterator *iter = cell->portBitIterator();
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 2);
|
|
}
|
|
|
|
// ConcretePortMemberIterator1 exercise
|
|
TEST(ConcretePortTest, MemberIteratorBus) {
|
|
ConcreteLibrary lib("test_lib", "test.lib", false);
|
|
lib.setBusBrkts('[', ']');
|
|
ConcreteCell *cell = lib.makeCell("R6_REG4", true, "");
|
|
ConcretePort *bus = cell->makeBusPort("D", 3, 0);
|
|
ConcretePortMemberIterator *iter = bus->memberIterator();
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
ConcretePort *member = iter->next();
|
|
EXPECT_NE(member, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 4);
|
|
}
|
|
|
|
// ConcreteInstanceChildIterator exercise
|
|
TEST_F(ConcreteNetworkLinkedTest, ChildIteratorExercise) {
|
|
Instance *top = network_.topInstance();
|
|
InstanceChildIterator *iter = network_.childIterator(top);
|
|
ASSERT_NE(iter, nullptr);
|
|
InstanceSeq children;
|
|
while (iter->hasNext()) {
|
|
children.push_back(iter->next());
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(children.size(), 2u);
|
|
}
|
|
|
|
// Network: connect with LibertyPort (null liberty port variant)
|
|
TEST_F(ConcreteNetworkLinkedTest, ConnectWithPort) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *u8 = network_.makeInstance(inv_cell, "u8_conn", network_.topInstance());
|
|
Port *port_y = network_.findPort(inv_cell, "Y");
|
|
Net *net = network_.makeNet("r6_conn_net", network_.topInstance());
|
|
Pin *pin = network_.connect(u8, port_y, net);
|
|
EXPECT_NE(pin, nullptr);
|
|
EXPECT_EQ(network_.net(pin), net);
|
|
}
|
|
|
|
// Network: deletePin (exercises ConcreteInstance::deletePin)
|
|
TEST_F(ConcreteNetworkLinkedTest, DeletePinExercise) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *u9 = network_.makeInstance(inv_cell, "u9_delpin", network_.topInstance());
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Net *net = network_.makeNet("r6_delpin_net", network_.topInstance());
|
|
Pin *pin = network_.connect(u9, port_a, net);
|
|
EXPECT_NE(pin, nullptr);
|
|
network_.disconnectPin(pin);
|
|
network_.deletePin(pin);
|
|
Pin *found = network_.findPin(u9, "A");
|
|
EXPECT_EQ(found, nullptr);
|
|
}
|
|
|
|
// BusPort: default constructor exercises (via makeBusPort)
|
|
TEST(ConcretePortTest, BusPortDefaultCtor) {
|
|
ConcreteLibrary lib("test_lib", "test.lib", false);
|
|
lib.setBusBrkts('[', ']');
|
|
ConcreteCell *cell = lib.makeCell("R6_BUSTEST", true, "");
|
|
ConcretePort *bus = cell->makeBusPort("Q", 0, 3);
|
|
EXPECT_NE(bus, nullptr);
|
|
EXPECT_TRUE(bus->isBus());
|
|
EXPECT_EQ(bus->fromIndex(), 0);
|
|
EXPECT_EQ(bus->toIndex(), 3);
|
|
EXPECT_EQ(bus->size(), 4);
|
|
}
|
|
|
|
// BusPort: setDirection propagates to members
|
|
TEST(ConcretePortTest, BusPortSetDirection) {
|
|
PortDirection::init();
|
|
ConcreteLibrary lib("test_lib", "test.lib", false);
|
|
lib.setBusBrkts('[', ']');
|
|
ConcreteCell *cell = lib.makeCell("R6_BUSDIR", true, "");
|
|
ConcretePort *bus = cell->makeBusPort("D", 1, 0);
|
|
bus->setDirection(PortDirection::output());
|
|
EXPECT_EQ(bus->direction(), PortDirection::output());
|
|
ConcretePort *bit0 = bus->findBusBit(0);
|
|
if (bit0) {
|
|
EXPECT_EQ(bit0->direction(), PortDirection::output());
|
|
}
|
|
}
|
|
|
|
// NetworkNameAdapter: makeLibertyLibrary forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterMakeLibertyLibrary) {
|
|
LibertyLibrary *lib = sdc_net_->makeLibertyLibrary("r6_lib", "r6.lib");
|
|
EXPECT_NE(lib, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: findCellsMatching forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterFindCellsMatching) {
|
|
PatternMatch pattern("BUF*");
|
|
CellSeq cells = sdc_net_->findCellsMatching(lib_, &pattern);
|
|
EXPECT_GE(cells.size(), 1u);
|
|
}
|
|
|
|
// NetworkNameAdapter: isLinked forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterIsLinked) {
|
|
EXPECT_TRUE(sdc_net_->isLinked());
|
|
}
|
|
|
|
// NetworkNameAdapter: connect(Instance, LibertyPort, Net) cannot be tested
|
|
// without an actual LibertyPort, so skip.
|
|
|
|
// Network: findPin(Instance, Port) with non-matching port
|
|
TEST_F(ConcreteNetworkLinkedTest, FindPinNonMatchingPort) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Port *port_y = network_.findPort(inv_cell, "Y");
|
|
// u1_ is connected on A and Y, find Y pin
|
|
Pin *pin = network_.findPin(u1_, port_y);
|
|
EXPECT_EQ(pin, pin_u1_y_);
|
|
}
|
|
|
|
// Network: findPinsMatching with no match
|
|
TEST_F(ConcreteNetworkLinkedTest, FindPinsMatchingNoMatch) {
|
|
Instance *top = network_.topInstance();
|
|
PatternMatch pattern("nonexistent/*");
|
|
PinSeq pins = network_.findPinsMatching(top, &pattern);
|
|
EXPECT_EQ(pins.size(), 0u);
|
|
}
|
|
|
|
// Network: findNetsMatching with no match
|
|
TEST_F(ConcreteNetworkLinkedTest, FindNetsMatchingNoMatch) {
|
|
Instance *top = network_.topInstance();
|
|
PatternMatch pattern("zzz*");
|
|
NetSeq matches = network_.findNetsMatching(top, &pattern);
|
|
EXPECT_EQ(matches.size(), 0u);
|
|
}
|
|
|
|
// Network: findInstancesMatching with no match
|
|
TEST_F(ConcreteNetworkLinkedTest, FindInstancesMatchingNoMatch) {
|
|
Instance *top = network_.topInstance();
|
|
PatternMatch pattern("zzz*");
|
|
InstanceSeq matches = network_.findInstancesMatching(top, &pattern);
|
|
EXPECT_EQ(matches.size(), 0u);
|
|
}
|
|
|
|
// ConcreteNetwork: initPins via makePins on new instance
|
|
TEST_F(ConcreteNetworkLinkedTest, InitPinsExercise) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *u10 = network_.makeInstance(inv_cell, "u10_init", network_.topInstance());
|
|
network_.makePins(u10);
|
|
Pin *pin_a = network_.findPin(u10, "A");
|
|
Pin *pin_y = network_.findPin(u10, "Y");
|
|
EXPECT_NE(pin_a, nullptr);
|
|
EXPECT_NE(pin_y, nullptr);
|
|
}
|
|
|
|
// ConcreteNetwork: mergeInto and mergedInto cycle
|
|
TEST_F(ConcreteNetworkLinkedTest, MergeIntoCycle) {
|
|
Instance *top = network_.topInstance();
|
|
Net *na = network_.makeNet("r6_merge_a", top);
|
|
Net *nb = network_.makeNet("r6_merge_b", top);
|
|
network_.mergeInto(na, nb);
|
|
EXPECT_EQ(network_.mergedInto(na), nb);
|
|
EXPECT_EQ(network_.mergedInto(nb), nullptr);
|
|
}
|
|
|
|
// ConcreteNetwork: connect via LibertyPort (exercises connect(Inst, LibertyPort, Net))
|
|
// This goes through ConcreteNetwork::connect which dispatches to connect(Inst, Port, Net)
|
|
// Can't easily test without real LibertyPort, skip.
|
|
|
|
// PatternMatch: exercise findPortsMatching with wildcard
|
|
TEST_F(ConcreteNetworkLinkedTest, FindPortsMatchingWildcard) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
PatternMatch pattern("?");
|
|
PortSeq ports = network_.findPortsMatching(inv_cell, &pattern);
|
|
// "A" and "Y" both match "?"
|
|
EXPECT_EQ(ports.size(), 2u);
|
|
}
|
|
|
|
// ConcreteNetwork: findCellsMatching with no match
|
|
TEST_F(ConcreteNetworkLinkedTest, FindCellsMatchingNoMatch) {
|
|
PatternMatch pattern("ZZZZ*");
|
|
CellSeq cells = network_.findCellsMatching(lib_, &pattern);
|
|
EXPECT_EQ(cells.size(), 0u);
|
|
}
|
|
|
|
// Network: isInsideNet with non-top instance
|
|
TEST_F(ConcreteNetworkLinkedTest, IsInsideNetNonTop) {
|
|
// net1_ is in top, not inside u1_
|
|
EXPECT_FALSE(network_.isInside(net1_, u1_));
|
|
}
|
|
|
|
// ConcreteNetwork: multiple connect/disconnect cycles
|
|
TEST_F(ConcreteNetworkLinkedTest, ConnectDisconnectCycle) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *u11 = network_.makeInstance(inv_cell, "u11_cycle", network_.topInstance());
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Net *net = network_.makeNet("r6_cycle_net", network_.topInstance());
|
|
|
|
// Connect
|
|
Pin *pin = network_.connect(u11, port_a, net);
|
|
EXPECT_NE(pin, nullptr);
|
|
EXPECT_EQ(network_.net(pin), net);
|
|
|
|
// Disconnect
|
|
network_.disconnectPin(pin);
|
|
EXPECT_EQ(network_.net(pin), nullptr);
|
|
|
|
// Reconnect to different net
|
|
Net *net2 = network_.makeNet("r6_cycle_net2", network_.topInstance());
|
|
Pin *pin2 = network_.connect(u11, port_a, net2);
|
|
EXPECT_NE(pin2, nullptr);
|
|
EXPECT_EQ(network_.net(pin2), net2);
|
|
}
|
|
|
|
// ConcreteBindingTbl: only exercised through linkReaderNetwork which
|
|
// is complex. Skip direct testing.
|
|
|
|
// SdcNetwork: findChild forwarding with non-existent
|
|
TEST_F(NetworkAdapterTest, SdcFindChildNonexistent) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Instance *child = sdc_net_->findChild(top, "nonexistent");
|
|
EXPECT_EQ(child, nullptr);
|
|
}
|
|
|
|
// SdcNetwork: findNet with non-existent
|
|
TEST_F(NetworkAdapterTest, SdcFindNetNonexistent) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Net *found = sdc_net_->findNet(top, "nonexistent");
|
|
EXPECT_EQ(found, nullptr);
|
|
}
|
|
|
|
// SdcNetwork: findPin with non-existent path
|
|
TEST_F(NetworkAdapterTest, SdcFindPinNonexistent) {
|
|
Pin *found = sdc_net_->findPin("nonexistent/X");
|
|
EXPECT_EQ(found, nullptr);
|
|
}
|
|
|
|
// SdcNetwork: findInstance with non-existent path
|
|
TEST_F(NetworkAdapterTest, SdcFindInstanceNonexistent) {
|
|
Instance *found = sdc_net_->findInstance("nonexistent_inst");
|
|
EXPECT_EQ(found, nullptr);
|
|
}
|
|
|
|
// SdcNetwork: deleteNet forwarding
|
|
TEST_F(NetworkAdapterTest, SdcDeleteNet) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Net *n = sdc_net_->makeNet("r6_sdc_delnet", top);
|
|
EXPECT_NE(n, nullptr);
|
|
sdc_net_->deleteNet(n);
|
|
Net *found = sdc_net_->findNet(top, "r6_sdc_delnet");
|
|
EXPECT_EQ(found, nullptr);
|
|
}
|
|
|
|
// SdcNetwork: libertyCell on cell (no liberty cell)
|
|
TEST_F(NetworkAdapterTest, SdcLibertyCellFromCell) {
|
|
LibertyCell *lc = sdc_net_->libertyCell(inv_cell_);
|
|
EXPECT_EQ(lc, nullptr);
|
|
}
|
|
|
|
// SdcNetwork: libertyPort from port
|
|
TEST_F(NetworkAdapterTest, SdcLibertyPortFromPort) {
|
|
LibertyPort *lp = sdc_net_->libertyPort(port_a_);
|
|
EXPECT_EQ(lp, nullptr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// R7_ tests for additional network coverage
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// ConcreteInstance::findChild on instance with no children
|
|
TEST_F(ConcreteNetworkLinkedTest, FindChildNonexistent) {
|
|
// u1_ is a leaf instance, should have no children
|
|
Instance *child = network_.findChild(u1_, "nonexistent");
|
|
EXPECT_EQ(child, nullptr);
|
|
}
|
|
|
|
// ConcreteInstance::findPin(Port) - exercise via Network::findPin(Instance*, Port*)
|
|
TEST_F(ConcreteNetworkLinkedTest, FindPinByPort3) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Pin *pin = network_.findPin(u1_, port_a);
|
|
EXPECT_NE(pin, nullptr);
|
|
EXPECT_EQ(pin, pin_u1_a_);
|
|
}
|
|
|
|
// ConcretePin::name() - exercises the name() method on concrete pins
|
|
TEST_F(ConcreteNetworkLinkedTest, PinName2) {
|
|
const char *name = network_.name(network_.port(pin_u1_a_));
|
|
EXPECT_NE(name, nullptr);
|
|
EXPECT_STREQ(name, "A");
|
|
}
|
|
|
|
// ConcretePin::setVertexId - exercises via Network::setVertexId
|
|
TEST_F(ConcreteNetworkLinkedTest, PinVertexId2) {
|
|
VertexId orig = network_.vertexId(pin_u1_a_);
|
|
network_.setVertexId(pin_u1_a_, 42);
|
|
EXPECT_EQ(network_.vertexId(pin_u1_a_), 42u);
|
|
// Restore
|
|
network_.setVertexId(pin_u1_a_, orig);
|
|
}
|
|
|
|
// ConcreteNet: term iterator (exercises ConcreteNetTermIterator)
|
|
TEST_F(ConcreteNetworkLinkedTest, NetTermIterator2) {
|
|
NetTermIterator *iter = network_.termIterator(net1_);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
// net1_ has pins from leaf instances, which don't have terms
|
|
EXPECT_GE(count, 0);
|
|
}
|
|
|
|
// ConcreteNet: pin iterator (exercises ConcreteNetPinIterator)
|
|
TEST_F(ConcreteNetworkLinkedTest, NetPinIterator2) {
|
|
NetPinIterator *iter = network_.pinIterator(net2_);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
// net2_ connects u1_/Y and u2_/A
|
|
EXPECT_EQ(count, 2);
|
|
}
|
|
|
|
// Network::makeTerm (exercises ConcreteTerm constructor and ConcreteNet::addTerm)
|
|
TEST_F(ConcreteNetworkLinkedTest, MakeTermAndTermName) {
|
|
// Make a top-level pin to create a term
|
|
Instance *top = network_.topInstance();
|
|
Cell *top_cell = network_.cell(top);
|
|
Port *clk_port = network_.findPort(top_cell, "clk");
|
|
Net *term_net = network_.makeNet("r7_term_net", top);
|
|
Pin *top_pin = network_.connect(top, clk_port, term_net);
|
|
EXPECT_NE(top_pin, nullptr);
|
|
// Top-level pins should have terms
|
|
Term *term = network_.term(top_pin);
|
|
if (term) {
|
|
// Exercises ConcreteTerm::name()
|
|
// Exercise Term accessors
|
|
Net *tnet_check = network_.net(term);
|
|
// Exercises NetworkNameAdapter::id(Term)
|
|
ObjectId tid = network_.id(term);
|
|
EXPECT_GE(tid, 0u);
|
|
// Term net should be the net we connected to
|
|
Net *tnet = network_.net(term);
|
|
EXPECT_EQ(tnet, term_net);
|
|
// Term pin should be the pin
|
|
Pin *tpin = network_.pin(term);
|
|
EXPECT_EQ(tpin, top_pin);
|
|
}
|
|
}
|
|
|
|
// Network::findPinLinear - exercises the linear search fallback
|
|
TEST_F(ConcreteNetworkLinkedTest, FindPinLinear) {
|
|
// findPinLinear is a fallback used when there's no hash lookup
|
|
Pin *pin = network_.findPin(u1_, "A");
|
|
EXPECT_NE(pin, nullptr);
|
|
// Non-existent port
|
|
Pin *no_pin = network_.findPin(u1_, "nonexistent");
|
|
EXPECT_EQ(no_pin, nullptr);
|
|
}
|
|
|
|
// Network::findNetLinear - exercises linear net search
|
|
TEST_F(ConcreteNetworkLinkedTest, FindNetLinear) {
|
|
Instance *top = network_.topInstance();
|
|
Net *net = network_.findNet(top, "n1");
|
|
EXPECT_NE(net, nullptr);
|
|
Net *no_net = network_.findNet(top, "nonexistent_net");
|
|
EXPECT_EQ(no_net, nullptr);
|
|
}
|
|
|
|
// Network::hasMembers on scalar port and bus port
|
|
TEST(ConcretePortTest, HasMembersScalar) {
|
|
ConcreteLibrary lib("test_lib", "test.lib", false);
|
|
lib.setBusBrkts('[', ']');
|
|
ConcreteCell *cell = lib.makeCell("R7_HAS", true, "");
|
|
ConcretePort *scalar = cell->makePort("A");
|
|
EXPECT_FALSE(scalar->hasMembers());
|
|
ConcretePort *bus = cell->makeBusPort("D", 1, 0);
|
|
EXPECT_TRUE(bus->hasMembers());
|
|
}
|
|
|
|
// R7_LibertyLibraryFromInstance removed (segfault)
|
|
|
|
// R7_LibertyLibraryFromCell removed (segfault)
|
|
|
|
// ConcreteInstance::initPins - exercised when making a new instance
|
|
TEST_F(ConcreteNetworkLinkedTest, InitPinsNewInstance) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *new_inst = network_.makeInstance(inv_cell, "r7_initpins", network_.topInstance());
|
|
EXPECT_NE(new_inst, nullptr);
|
|
// After making instance, pins should be initialized
|
|
network_.makePins(new_inst);
|
|
// Should be able to find pins
|
|
InstancePinIterator *iter = network_.pinIterator(new_inst);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
// INV has 2 ports: A, Y
|
|
EXPECT_EQ(count, 2);
|
|
}
|
|
|
|
// ConcreteNetwork::deleteInstance (exercises deleteChild, deletePin)
|
|
TEST_F(ConcreteNetworkLinkedTest, DeleteInstance2) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *del_inst = network_.makeInstance(inv_cell, "r7_del", network_.topInstance());
|
|
EXPECT_NE(del_inst, nullptr);
|
|
Instance *found = network_.findChild(network_.topInstance(), "r7_del");
|
|
EXPECT_NE(found, nullptr);
|
|
network_.deleteInstance(del_inst);
|
|
Instance *gone = network_.findChild(network_.topInstance(), "r7_del");
|
|
EXPECT_EQ(gone, nullptr);
|
|
}
|
|
|
|
// ConcreteNetwork: deleteNet (exercises ConcreteNet destructor, ConcreteInstance::deleteNet)
|
|
TEST_F(ConcreteNetworkLinkedTest, DeleteNet2) {
|
|
Instance *top = network_.topInstance();
|
|
Net *del_net = network_.makeNet("r7_del_net", top);
|
|
EXPECT_NE(del_net, nullptr);
|
|
Net *found = network_.findNet(top, "r7_del_net");
|
|
EXPECT_NE(found, nullptr);
|
|
network_.deleteNet(del_net);
|
|
Net *gone = network_.findNet(top, "r7_del_net");
|
|
EXPECT_EQ(gone, nullptr);
|
|
}
|
|
|
|
// ConcreteInstance::setCell (indirect via replaceCell)
|
|
TEST_F(ConcreteNetworkLinkedTest, ReplaceCell2) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
// Create a second cell type
|
|
Cell *buf_cell = network_.makeCell(lib_, "R7_BUF", true, "test.lib");
|
|
network_.makePort(buf_cell, "A");
|
|
network_.makePort(buf_cell, "Y");
|
|
Instance *inst = network_.makeInstance(inv_cell, "r7_replace", network_.topInstance());
|
|
EXPECT_STREQ(network_.name(network_.cell(inst)), "INV");
|
|
network_.replaceCell(inst, buf_cell);
|
|
EXPECT_STREQ(network_.name(network_.cell(inst)), "R7_BUF");
|
|
}
|
|
|
|
// ConcreteInstance::addNet via makeNet and findNet on child instance
|
|
TEST_F(ConcreteNetworkLinkedTest, InstanceNet) {
|
|
// Make net on a non-top instance (exercises ConcreteInstance::addNet(name, net))
|
|
Cell *sub_cell = network_.makeCell(lib_, "R7_SUB", false, "test.lib");
|
|
network_.makePort(sub_cell, "in1");
|
|
Instance *sub = network_.makeInstance(sub_cell, "r7_sub", network_.topInstance());
|
|
Net *sub_net = network_.makeNet("r7_sub_net", sub);
|
|
EXPECT_NE(sub_net, nullptr);
|
|
Net *found = network_.findNet(sub, "r7_sub_net");
|
|
EXPECT_EQ(found, sub_net);
|
|
}
|
|
|
|
// NetworkNameAdapter: findPort forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterFindPort2) {
|
|
Port *port = sdc_net_->findPort(inv_cell_, "A");
|
|
EXPECT_NE(port, nullptr);
|
|
EXPECT_EQ(port, port_a_);
|
|
}
|
|
|
|
// NetworkNameAdapter: findPortsMatching forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterFindPortsMatching2) {
|
|
PatternMatch pattern("*");
|
|
PortSeq ports = sdc_net_->findPortsMatching(inv_cell_, &pattern);
|
|
EXPECT_GE(ports.size(), 2u);
|
|
}
|
|
|
|
// NetworkNameAdapter: name(Port) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPortName2) {
|
|
const char *name = sdc_net_->name(port_a_);
|
|
EXPECT_NE(name, nullptr);
|
|
EXPECT_STREQ(name, "A");
|
|
}
|
|
|
|
// NetworkNameAdapter: busName(Port) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPortBusName2) {
|
|
const char *bname = sdc_net_->busName(port_a_);
|
|
EXPECT_NE(bname, nullptr);
|
|
}
|
|
|
|
// R7_AdapterFindBusBit removed (segfault)
|
|
|
|
// R7_AdapterFindMember removed (segfault)
|
|
|
|
// R7_AdapterFindPinLibertyPort removed (segfault)
|
|
|
|
// NetworkNameAdapter: id(Term) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterTermId) {
|
|
// Make a top-level pin to get a term
|
|
Instance *top = sdc_net_->topInstance();
|
|
Cell *top_cell = sdc_net_->cell(top);
|
|
Port *in1 = sdc_net_->findPort(top_cell, "in1");
|
|
Net *tnet = sdc_net_->makeNet("r7_term_net2", top);
|
|
Pin *tpin = sdc_net_->connect(top, in1, tnet);
|
|
EXPECT_NE(tpin, nullptr);
|
|
Term *term = sdc_net_->term(tpin);
|
|
if (term) {
|
|
ObjectId tid = sdc_net_->id(term);
|
|
EXPECT_GE(tid, 0u);
|
|
}
|
|
}
|
|
|
|
// NetworkNameAdapter: makeNet forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterMakeNet2) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Net *net = sdc_net_->makeNet("r7_adapter_net", top);
|
|
EXPECT_NE(net, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter: connect(Instance, Port, Net) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterConnect2) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Net *net = sdc_net_->makeNet("r7_adapter_conn_net", top);
|
|
// makeInstance requires LibertyCell, get it from the network
|
|
LibertyCell *lib_cell = sdc_net_->findLibertyCell("INV_X1");
|
|
if (lib_cell) {
|
|
Instance *inst = sdc_net_->makeInstance(lib_cell, "r7_adapter_inst", top);
|
|
EXPECT_NE(inst, nullptr);
|
|
}
|
|
}
|
|
|
|
// Network::findNetsMatchingLinear exercises
|
|
TEST_F(ConcreteNetworkLinkedTest, FindNetsMatchingLinear) {
|
|
Instance *top = network_.topInstance();
|
|
PatternMatch pattern("n*");
|
|
NetSeq matches = network_.findNetsMatching(top, &pattern);
|
|
// Should match n1, n2, n3
|
|
EXPECT_GE(matches.size(), 3u);
|
|
}
|
|
|
|
// ConcreteNetwork: addConstantNet and clearConstantNets
|
|
TEST_F(ConcreteNetworkLinkedTest, ConstantNets) {
|
|
Instance *top = network_.topInstance();
|
|
Net *const_net = network_.makeNet("r7_const", top);
|
|
network_.addConstantNet(const_net, LogicValue::one);
|
|
// constantPinIterator should work
|
|
ConstantPinIterator *iter = network_.constantPinIterator();
|
|
ASSERT_NE(iter, nullptr);
|
|
delete iter;
|
|
// Clear exercises clearConstantNets
|
|
network_.clear();
|
|
}
|
|
|
|
// ConcreteLibertyLibraryIterator exercise
|
|
TEST(ConcreteNetworkTest, LibertyLibraryIterator) {
|
|
ConcreteNetwork network;
|
|
LibertyLibraryIterator *iter = network.libertyLibraryIterator();
|
|
ASSERT_NE(iter, nullptr);
|
|
EXPECT_FALSE(iter->hasNext());
|
|
delete iter;
|
|
}
|
|
|
|
// ConcreteLibraryIterator1 exercise
|
|
TEST(ConcreteNetworkTest, LibraryIteratorEmpty) {
|
|
ConcreteNetwork network;
|
|
LibraryIterator *iter = network.libraryIterator();
|
|
ASSERT_NE(iter, nullptr);
|
|
EXPECT_FALSE(iter->hasNext());
|
|
delete iter;
|
|
}
|
|
|
|
// ConcreteInstancePinIterator exercise
|
|
TEST_F(ConcreteNetworkLinkedTest, InstancePinIterator2) {
|
|
InstancePinIterator *iter = network_.pinIterator(u1_);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
Pin *pin = iter->next();
|
|
EXPECT_NE(pin, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
// INV has 2 pins: A and Y
|
|
EXPECT_EQ(count, 2);
|
|
}
|
|
|
|
// Network: mergeInto exercises (ConcreteNet::mergeInto path)
|
|
TEST_F(ConcreteNetworkLinkedTest, MergeNets) {
|
|
Instance *top = network_.topInstance();
|
|
Net *na = network_.makeNet("r7_merge_a", top);
|
|
Net *nb = network_.makeNet("r7_merge_b", top);
|
|
network_.mergeInto(na, nb);
|
|
Net *merged = network_.mergedInto(na);
|
|
EXPECT_EQ(merged, nb);
|
|
}
|
|
|
|
// BusPort: setDirection exercises BusPort::setDirection
|
|
TEST(ConcretePortTest, BusPortSetDirectionInput) {
|
|
PortDirection::init();
|
|
ConcreteLibrary lib("test_lib", "test.lib", false);
|
|
lib.setBusBrkts('[', ']');
|
|
ConcreteCell *cell = lib.makeCell("R7_BDIR", true, "");
|
|
ConcretePort *bus = cell->makeBusPort("IN", 3, 0);
|
|
bus->setDirection(PortDirection::input());
|
|
EXPECT_EQ(bus->direction(), PortDirection::input());
|
|
// Verify bits got the direction too
|
|
for (int i = 0; i <= 3; i++) {
|
|
ConcretePort *bit = bus->findBusBit(i);
|
|
if (bit) {
|
|
EXPECT_EQ(bit->direction(), PortDirection::input());
|
|
}
|
|
}
|
|
}
|
|
|
|
// R7_CheckLibertyCorners removed (segfault)
|
|
|
|
// R7_AdapterLinkNetwork removed (segfault)
|
|
|
|
// ConcreteNetwork: findAnyCell
|
|
TEST_F(ConcreteNetworkLinkedTest, FindAnyCell) {
|
|
Cell *cell = network_.findAnyCell("INV");
|
|
EXPECT_NE(cell, nullptr);
|
|
Cell *no_cell = network_.findAnyCell("NONEXISTENT_R7");
|
|
EXPECT_EQ(no_cell, nullptr);
|
|
}
|
|
|
|
// ConcreteNetwork: isPower/isGround on net
|
|
TEST_F(ConcreteNetworkLinkedTest, NetPowerGround) {
|
|
EXPECT_FALSE(network_.isPower(net1_));
|
|
EXPECT_FALSE(network_.isGround(net1_));
|
|
}
|
|
|
|
// ConcreteNetwork: net instance
|
|
TEST_F(ConcreteNetworkLinkedTest, NetInstance2) {
|
|
Instance *inst = network_.instance(net1_);
|
|
EXPECT_EQ(inst, network_.topInstance());
|
|
}
|
|
|
|
// Network: cellName convenience
|
|
TEST_F(ConcreteNetworkLinkedTest, CellNameConvenience) {
|
|
const char *name = network_.cellName(u2_);
|
|
EXPECT_STREQ(name, "INV");
|
|
}
|
|
|
|
// ConcreteNetwork: pin direction
|
|
TEST_F(ConcreteNetworkLinkedTest, PinDirection2) {
|
|
PortDirection *dir = network_.direction(pin_u1_a_);
|
|
EXPECT_NE(dir, nullptr);
|
|
EXPECT_TRUE(dir->isInput());
|
|
}
|
|
|
|
// NetworkNameAdapter: hasMembers on scalar port
|
|
TEST_F(NetworkAdapterTest, AdapterHasMembers) {
|
|
bool has = sdc_net_->hasMembers(port_a_);
|
|
EXPECT_FALSE(has);
|
|
}
|
|
|
|
// ConcreteNetwork: disconnectPin and reconnect cycle
|
|
TEST_F(ConcreteNetworkLinkedTest, DisconnectReconnect) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *inst = network_.makeInstance(inv_cell, "r7_disc", network_.topInstance());
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Net *net_a = network_.makeNet("r7_disc_net", network_.topInstance());
|
|
Pin *pin = network_.connect(inst, port_a, net_a);
|
|
EXPECT_NE(pin, nullptr);
|
|
EXPECT_EQ(network_.net(pin), net_a);
|
|
network_.disconnectPin(pin);
|
|
EXPECT_EQ(network_.net(pin), nullptr);
|
|
// Reconnect
|
|
Net *net_b = network_.makeNet("r7_disc_net2", network_.topInstance());
|
|
Pin *pin2 = network_.connect(inst, port_a, net_b);
|
|
EXPECT_NE(pin2, nullptr);
|
|
EXPECT_EQ(network_.net(pin2), net_b);
|
|
}
|
|
|
|
// ConcreteNetwork: instance attribute
|
|
TEST_F(ConcreteNetworkLinkedTest, InstanceAttribute) {
|
|
network_.setAttribute(u1_, "r7_key", "r7_value");
|
|
std::string val = network_.getAttribute(u1_, "r7_key");
|
|
EXPECT_EQ(val, "r7_value");
|
|
std::string no_val = network_.getAttribute(u1_, "nonexistent_r7");
|
|
EXPECT_TRUE(no_val.empty());
|
|
}
|
|
|
|
// ConcreteNetwork: instance net iterator
|
|
TEST_F(ConcreteNetworkLinkedTest, InstanceNetIterator2) {
|
|
// Net iterator on a child instance with local nets
|
|
Cell *sub_cell = network_.makeCell(lib_, "R7_SUBC", false, "test.lib");
|
|
network_.makePort(sub_cell, "p1");
|
|
Instance *sub = network_.makeInstance(sub_cell, "r7_neti", network_.topInstance());
|
|
Net *local_net = network_.makeNet("r7_local", sub);
|
|
EXPECT_NE(local_net, nullptr);
|
|
InstanceNetIterator *iter = network_.netIterator(sub);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_GE(count, 1);
|
|
}
|
|
|
|
// Network: visitConnectedPins exercises (through connectedPins API)
|
|
TEST_F(ConcreteNetworkLinkedTest, ConnectedPins) {
|
|
// Exercise connectedPinIterator as an alternative
|
|
ConnectedPinIterator *iter = network_.connectedPinIterator(pin_u1_a_);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_GE(count, 1);
|
|
}
|
|
|
|
// ConcreteNetwork: portBitCount
|
|
TEST_F(ConcreteNetworkLinkedTest, PortBitCount) {
|
|
Cell *cell = network_.cell(u1_);
|
|
int count = network_.portBitCount(cell);
|
|
// INV has A and Y = 2 bit ports
|
|
EXPECT_EQ(count, 2);
|
|
}
|
|
|
|
// ConcreteNetwork: setCellNetworkView / cellNetworkView
|
|
TEST_F(ConcreteNetworkLinkedTest, CellNetworkView) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
// Initially null
|
|
Instance *view = network_.cellNetworkView(inv_cell);
|
|
EXPECT_EQ(view, nullptr);
|
|
// Set and get
|
|
network_.setCellNetworkView(inv_cell, u1_);
|
|
view = network_.cellNetworkView(inv_cell);
|
|
EXPECT_EQ(view, u1_);
|
|
// Delete all views
|
|
network_.deleteCellNetworkViews();
|
|
view = network_.cellNetworkView(inv_cell);
|
|
EXPECT_EQ(view, nullptr);
|
|
}
|
|
|
|
// R7_AdapterMakeInstanceLiberty removed (segfault)
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// R8_ tests for additional network coverage
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// ConcreteNetwork::connect(Instance*, LibertyPort*, Net*) - uncovered overload
|
|
TEST_F(ConcreteNetworkLinkedTest, ConnectWithLibertyPort) {
|
|
// connect with LibertyPort* just forwards to connect with Port*
|
|
// Since we don't have a real LibertyPort, test the Port-based connect path
|
|
Instance *top = network_.topInstance();
|
|
Net *extra_net = network_.makeNet("extra_n", top);
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *u3 = network_.makeInstance(inv_cell, "u3", top);
|
|
Port *inv_a = network_.findPort(inv_cell, "A");
|
|
Pin *pin = network_.connect(u3, inv_a, extra_net);
|
|
EXPECT_NE(pin, nullptr);
|
|
EXPECT_EQ(network_.net(pin), extra_net);
|
|
// Clean up
|
|
network_.disconnectPin(pin);
|
|
network_.deleteInstance(u3);
|
|
network_.deleteNet(extra_net);
|
|
}
|
|
|
|
// ConcreteNetwork::clearConstantNets
|
|
TEST_F(ConcreteNetworkLinkedTest, ClearConstantNets) {
|
|
// Add constant nets and clear them
|
|
network_.addConstantNet(net1_, LogicValue::zero);
|
|
network_.addConstantNet(net2_, LogicValue::one);
|
|
// Iterate to verify they exist
|
|
ConstantPinIterator *iter = network_.constantPinIterator();
|
|
EXPECT_NE(iter, nullptr);
|
|
delete iter;
|
|
// clearConstantNets is called implicitly by clear()
|
|
// We can't call it directly since it's protected, but we can verify
|
|
// the constant nets are accessible via the non-null iterator above
|
|
}
|
|
|
|
// ConcreteInstance::cell() const - uncovered
|
|
TEST_F(ConcreteNetworkLinkedTest, InstanceCell2) {
|
|
Cell *cell = network_.cell(u1_);
|
|
EXPECT_NE(cell, nullptr);
|
|
// Verify it's the INV cell
|
|
EXPECT_STREQ(network_.name(cell), "INV");
|
|
}
|
|
|
|
// ConcreteInstance::findChild - exercise child lookup
|
|
TEST_F(ConcreteNetworkLinkedTest, FindChildInstance) {
|
|
Instance *top = network_.topInstance();
|
|
Instance *child = network_.findChild(top, "u1");
|
|
EXPECT_EQ(child, u1_);
|
|
Instance *no_child = network_.findChild(top, "nonexistent_child");
|
|
EXPECT_EQ(no_child, nullptr);
|
|
}
|
|
|
|
// ConcreteInstance::findPin(Port*) - uncovered overload
|
|
TEST_F(ConcreteNetworkLinkedTest, FindPinByPortDirect2) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Pin *pin = network_.findPin(u1_, port_a);
|
|
EXPECT_NE(pin, nullptr);
|
|
EXPECT_EQ(pin, pin_u1_a_);
|
|
}
|
|
|
|
// ConcreteInstance::deleteChild - exercise child deletion
|
|
TEST_F(ConcreteNetworkLinkedTest, DeleteChildInstance) {
|
|
Instance *top = network_.topInstance();
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *temp = network_.makeInstance(inv_cell, "temp_child", top);
|
|
EXPECT_NE(temp, nullptr);
|
|
Instance *found = network_.findChild(top, "temp_child");
|
|
EXPECT_EQ(found, temp);
|
|
network_.deleteInstance(temp);
|
|
found = network_.findChild(top, "temp_child");
|
|
EXPECT_EQ(found, nullptr);
|
|
}
|
|
|
|
// ConcreteInstance::addNet / deleteNet through ConcreteNetwork
|
|
TEST_F(ConcreteNetworkLinkedTest, AddDeleteNet) {
|
|
Instance *top = network_.topInstance();
|
|
Net *new_net = network_.makeNet("test_net_r8", top);
|
|
EXPECT_NE(new_net, nullptr);
|
|
Net *found = network_.findNet(top, "test_net_r8");
|
|
EXPECT_EQ(found, new_net);
|
|
network_.deleteNet(new_net);
|
|
found = network_.findNet(top, "test_net_r8");
|
|
EXPECT_EQ(found, nullptr);
|
|
}
|
|
|
|
// ConcreteInstance::setCell
|
|
TEST_F(ConcreteNetworkLinkedTest, SetInstanceCell) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
// Replace u1 cell with same cell (exercises the path)
|
|
network_.replaceCell(u1_, inv_cell);
|
|
Cell *cell = network_.cell(u1_);
|
|
EXPECT_EQ(cell, inv_cell);
|
|
}
|
|
|
|
// ConcreteInstance::initPins - exercise pin initialization
|
|
TEST_F(ConcreteNetworkLinkedTest, InstanceInitPins) {
|
|
Instance *top = network_.topInstance();
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *u_new = network_.makeInstance(inv_cell, "u_init", top);
|
|
// makePins exercises initPins internally
|
|
network_.makePins(u_new);
|
|
// Verify we can iterate pins
|
|
InstancePinIterator *iter = network_.pinIterator(u_new);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 2); // INV has A and Y
|
|
network_.deleteInstance(u_new);
|
|
}
|
|
|
|
// ConcretePin: port and instance accessors
|
|
TEST_F(ConcreteNetworkLinkedTest, PinPortAndInstance) {
|
|
Port *port = network_.port(pin_u1_a_);
|
|
EXPECT_NE(port, nullptr);
|
|
Instance *inst = network_.instance(pin_u1_a_);
|
|
EXPECT_EQ(inst, u1_);
|
|
}
|
|
|
|
// ConcretePin::setVertexId - uncovered
|
|
TEST_F(ConcreteNetworkLinkedTest, PinSetVertexId) {
|
|
VertexId orig = network_.vertexId(pin_u1_a_);
|
|
network_.setVertexId(pin_u1_a_, 999);
|
|
EXPECT_EQ(network_.vertexId(pin_u1_a_), 999u);
|
|
network_.setVertexId(pin_u1_a_, orig);
|
|
}
|
|
|
|
// ConcreteNet::addPin / deletePin (through connect/disconnect)
|
|
TEST_F(ConcreteNetworkLinkedTest, NetPinManipulation) {
|
|
Instance *top = network_.topInstance();
|
|
Net *test_net = network_.makeNet("r8_net", top);
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *u_temp = network_.makeInstance(inv_cell, "u_r8", top);
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Pin *pin = network_.connect(u_temp, port_a, test_net);
|
|
EXPECT_NE(pin, nullptr);
|
|
|
|
// Verify pin is on net
|
|
NetPinIterator *iter = network_.pinIterator(test_net);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 1);
|
|
|
|
// Disconnect and verify
|
|
network_.disconnectPin(pin);
|
|
iter = network_.pinIterator(test_net);
|
|
count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 0);
|
|
|
|
network_.deleteInstance(u_temp);
|
|
network_.deleteNet(test_net);
|
|
}
|
|
|
|
// ConcreteNet::addTerm / deleteTerm (through makeTerm)
|
|
TEST_F(ConcreteNetworkLinkedTest, TermManipulation) {
|
|
Instance *top = network_.topInstance();
|
|
Cell *top_cell = network_.cell(top);
|
|
Port *clk_port = network_.findPort(top_cell, "clk");
|
|
Net *clk_net = network_.makeNet("clk_net_r8", top);
|
|
|
|
// Connect top-level port pin to net
|
|
Pin *top_pin = network_.connect(top, clk_port, clk_net);
|
|
EXPECT_NE(top_pin, nullptr);
|
|
|
|
// Make a term for the pin
|
|
Term *term = network_.makeTerm(top_pin, clk_net);
|
|
EXPECT_NE(term, nullptr);
|
|
|
|
// Get term's pin and net
|
|
Pin *term_pin = network_.pin(term);
|
|
EXPECT_EQ(term_pin, top_pin);
|
|
Net *term_net = network_.net(term);
|
|
EXPECT_EQ(term_net, clk_net);
|
|
|
|
// Term name
|
|
ObjectId tid = network_.id(term);
|
|
EXPECT_GT(tid, 0u);
|
|
|
|
// Verify term iterator on net
|
|
NetTermIterator *titer = network_.termIterator(clk_net);
|
|
int tcount = 0;
|
|
while (titer->hasNext()) {
|
|
titer->next();
|
|
tcount++;
|
|
}
|
|
delete titer;
|
|
EXPECT_GE(tcount, 1);
|
|
|
|
network_.disconnectPin(top_pin);
|
|
network_.deleteNet(clk_net);
|
|
}
|
|
|
|
// ConcreteNetPinIterator - uncovered constructor
|
|
TEST_F(ConcreteNetworkLinkedTest, NetPinIteratorEmpty) {
|
|
Instance *top = network_.topInstance();
|
|
Net *empty_net = network_.makeNet("empty_r8", top);
|
|
NetPinIterator *iter = network_.pinIterator(empty_net);
|
|
EXPECT_NE(iter, nullptr);
|
|
EXPECT_FALSE(iter->hasNext());
|
|
delete iter;
|
|
network_.deleteNet(empty_net);
|
|
}
|
|
|
|
// ConcreteNetTermIterator - uncovered constructor
|
|
TEST_F(ConcreteNetworkLinkedTest, NetTermIteratorEmpty2) {
|
|
Instance *top = network_.topInstance();
|
|
Net *empty_net = network_.makeNet("empty_term_r8", top);
|
|
NetTermIterator *iter = network_.termIterator(empty_net);
|
|
EXPECT_NE(iter, nullptr);
|
|
EXPECT_FALSE(iter->hasNext());
|
|
delete iter;
|
|
network_.deleteNet(empty_net);
|
|
}
|
|
|
|
// ConcreteLibraryIterator1 - uncovered
|
|
TEST_F(ConcreteNetworkLinkedTest, LibraryIterator) {
|
|
LibraryIterator *iter = network_.libraryIterator();
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
Library *lib = iter->next();
|
|
EXPECT_NE(lib, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_GE(count, 1);
|
|
}
|
|
|
|
// ConcreteLibertyLibraryIterator - uncovered
|
|
TEST_F(ConcreteNetworkLinkedTest, LibertyLibraryIterator) {
|
|
LibertyLibraryIterator *iter = network_.libertyLibraryIterator();
|
|
EXPECT_NE(iter, nullptr);
|
|
// No liberty libraries in our simple network, so it may be empty
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
// Count can be 0 - just verifying iteration completes
|
|
EXPECT_GE(count, 0);
|
|
}
|
|
|
|
// ConcreteCellPortIterator1 - uncovered
|
|
TEST_F(ConcreteNetworkLinkedTest, CellPortIterator) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
CellPortIterator *iter = network_.portIterator(inv_cell);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
Port *p = iter->next();
|
|
EXPECT_NE(p, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 2); // A and Y
|
|
}
|
|
|
|
// ConcreteCellPortBitIterator / ConcreteCellPortBitIterator1 - uncovered
|
|
TEST_F(ConcreteNetworkLinkedTest, CellPortBitIterator2) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
CellPortBitIterator *iter = network_.portBitIterator(inv_cell);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
Port *p = iter->next();
|
|
EXPECT_NE(p, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 2); // A and Y (scalar ports)
|
|
}
|
|
|
|
// ConcreteInstanceChildIterator - uncovered
|
|
TEST_F(ConcreteNetworkLinkedTest, InstanceChildIterator) {
|
|
Instance *top = network_.topInstance();
|
|
InstanceChildIterator *iter = network_.childIterator(top);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
Instance *child = iter->next();
|
|
EXPECT_NE(child, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 2); // u1 and u2
|
|
}
|
|
|
|
// ConcreteInstancePinIterator - uncovered constructor
|
|
TEST_F(ConcreteNetworkLinkedTest, InstancePinIteratorCount) {
|
|
InstancePinIterator *iter = network_.pinIterator(u1_);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
Pin *p = iter->next();
|
|
EXPECT_NE(p, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 2); // A and Y connected
|
|
}
|
|
|
|
// R8_LibertyLibraryOfInstance removed (segfault - no liberty in simple network)
|
|
// R8_LibertyLibraryOfCell removed (segfault - no liberty in simple network)
|
|
|
|
// Network::hasMembers - uncovered
|
|
TEST_F(ConcreteNetworkLinkedTest, HasMembers) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
bool has = network_.hasMembers(port_a);
|
|
EXPECT_FALSE(has); // scalar port
|
|
}
|
|
|
|
// Network::findPin with port name string
|
|
TEST_F(ConcreteNetworkLinkedTest, FindPinByName2) {
|
|
Pin *pin = network_.findPin(u1_, "A");
|
|
EXPECT_NE(pin, nullptr);
|
|
EXPECT_EQ(pin, pin_u1_a_);
|
|
Pin *no_pin = network_.findPin(u1_, "nonexistent");
|
|
EXPECT_EQ(no_pin, nullptr);
|
|
}
|
|
|
|
// Network::findPin(Instance*, Port*) - uncovered overload
|
|
TEST_F(ConcreteNetworkLinkedTest, FindPinByPortOverload) {
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Pin *pin = network_.findPin(u1_, port_a);
|
|
EXPECT_NE(pin, nullptr);
|
|
EXPECT_EQ(pin, pin_u1_a_);
|
|
}
|
|
|
|
// Network::findNet by name
|
|
TEST_F(ConcreteNetworkLinkedTest, FindNetByName2) {
|
|
Instance *top = network_.topInstance();
|
|
Net *net = network_.findNet(top, "n1");
|
|
EXPECT_NE(net, nullptr);
|
|
EXPECT_EQ(net, net1_);
|
|
Net *no_net = network_.findNet(top, "nonexistent_net");
|
|
EXPECT_EQ(no_net, nullptr);
|
|
}
|
|
|
|
// Network::findNetsMatching pattern
|
|
TEST_F(ConcreteNetworkLinkedTest, FindNetsMatching2) {
|
|
Instance *top = network_.topInstance();
|
|
PatternMatch pat("n*", false, false, nullptr);
|
|
NetSeq matches;
|
|
network_.findInstNetsMatching(top, &pat, matches);
|
|
EXPECT_GE(matches.size(), 3u); // n1, n2, n3
|
|
}
|
|
|
|
// ConcreteNetwork::mergeNets exercise
|
|
TEST_F(ConcreteNetworkLinkedTest, MergeNetsExercise) {
|
|
Instance *top = network_.topInstance();
|
|
Net *a = network_.makeNet("merge_a", top);
|
|
Net *b = network_.makeNet("merge_b", top);
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *u_merge = network_.makeInstance(inv_cell, "u_merge", top);
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Port *port_y = network_.findPort(inv_cell, "Y");
|
|
Pin *p1 = network_.connect(u_merge, port_a, a);
|
|
Pin *p2 = network_.connect(u_merge, port_y, b);
|
|
EXPECT_NE(p1, nullptr);
|
|
EXPECT_NE(p2, nullptr);
|
|
|
|
// Merge a into b
|
|
network_.mergeInto(a, b);
|
|
Net *merged = network_.mergedInto(a);
|
|
EXPECT_EQ(merged, b);
|
|
|
|
network_.deleteInstance(u_merge);
|
|
network_.deleteNet(b);
|
|
}
|
|
|
|
// NetworkNameAdapter forwarding tests via SdcNetwork
|
|
// NetworkNameAdapter::findPort
|
|
TEST_F(NetworkAdapterTest, AdapterFindPortByName) {
|
|
Port *port = sdc_net_->findPort(inv_cell_, "A");
|
|
EXPECT_NE(port, nullptr);
|
|
EXPECT_EQ(port, port_a_);
|
|
Port *no_port = sdc_net_->findPort(inv_cell_, "nonexistent");
|
|
EXPECT_EQ(no_port, nullptr);
|
|
}
|
|
|
|
// NetworkNameAdapter::findPortsMatching
|
|
TEST_F(NetworkAdapterTest, AdapterFindPortsMatching3) {
|
|
PatternMatch pat("*", false, false, nullptr);
|
|
PortSeq ports = sdc_net_->findPortsMatching(inv_cell_, &pat);
|
|
EXPECT_EQ(ports.size(), 2u); // A and Y
|
|
}
|
|
|
|
// NetworkNameAdapter::name(Port*) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterPortNameForward) {
|
|
const char *name = sdc_net_->name(port_a_);
|
|
EXPECT_STREQ(name, "A");
|
|
}
|
|
|
|
// NetworkNameAdapter::busName(Port*) forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterBusNameForward) {
|
|
const char *bname = sdc_net_->busName(port_a_);
|
|
EXPECT_STREQ(bname, "A"); // scalar port
|
|
}
|
|
|
|
// R8_AdapterFindBusBit removed (segfault)
|
|
// R8_AdapterFindMember removed (segfault)
|
|
// R8_AdapterFindPinLibertyPort removed (segfault)
|
|
// R8_AdapterLinkNetwork removed (segfault)
|
|
// R8_AdapterMakeInstanceNull removed (segfault)
|
|
|
|
// NetworkNameAdapter::makeNet forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterMakeNetForward) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Net *net = sdc_net_->makeNet("adapter_net_r8", top);
|
|
EXPECT_NE(net, nullptr);
|
|
EXPECT_STREQ(network_.name(net), "adapter_net_r8");
|
|
sdc_net_->deleteNet(net);
|
|
}
|
|
|
|
// NetworkNameAdapter::connect forwarding
|
|
TEST_F(NetworkAdapterTest, AdapterConnectForward) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Net *net = sdc_net_->makeNet("conn_r8", top);
|
|
Port *port_y = network_.findPort(inv_cell_, "Y");
|
|
Pin *pin = sdc_net_->connect(u1_, port_y, net);
|
|
EXPECT_NE(pin, nullptr);
|
|
sdc_net_->disconnectPin(pin);
|
|
sdc_net_->deleteNet(net);
|
|
}
|
|
|
|
// NetworkEdit::connectPin exercises
|
|
TEST_F(ConcreteNetworkLinkedTest, DisconnectAndReconnect) {
|
|
// Disconnect pin and reconnect to different net
|
|
Instance *top = network_.topInstance();
|
|
Net *alt_net = network_.makeNet("alt_r8", top);
|
|
network_.disconnectPin(pin_u1_a_);
|
|
EXPECT_EQ(network_.net(pin_u1_a_), nullptr);
|
|
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
pin_u1_a_ = network_.connect(u1_, port_a, alt_net);
|
|
EXPECT_NE(pin_u1_a_, nullptr);
|
|
EXPECT_EQ(network_.net(pin_u1_a_), alt_net);
|
|
|
|
// Reconnect to original
|
|
network_.disconnectPin(pin_u1_a_);
|
|
pin_u1_a_ = network_.connect(u1_, port_a, net1_);
|
|
network_.deleteNet(alt_net);
|
|
}
|
|
|
|
// ConcretePortMemberIterator1 - uncovered
|
|
TEST(ConcretePortR8Test, PortMemberIteratorOnBus) {
|
|
ConcreteLibrary lib("r8_lib", "r8.lib", false);
|
|
lib.setBusBrkts('[', ']');
|
|
ConcreteCell *cell = lib.makeCell("BUS_CELL", true, "");
|
|
ConcretePort *bus = cell->makeBusPort("D", 7, 0);
|
|
ConcretePortMemberIterator *iter = bus->memberIterator();
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
ConcretePort *member = iter->next();
|
|
EXPECT_NE(member, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 8);
|
|
}
|
|
|
|
// ConcretePortMemberIterator1 on scalar port - should have no members
|
|
TEST(ConcretePortR8Test, PortMemberIteratorOnScalar) {
|
|
ConcreteLibrary lib("r8_lib2", "r8.lib", false);
|
|
ConcreteCell *cell = lib.makeCell("SCALAR_CELL", true, "");
|
|
ConcretePort *port = cell->makePort("A");
|
|
ConcretePortMemberIterator *iter = port->memberIterator();
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 0);
|
|
}
|
|
|
|
// BusPort::setDirection - uncovered
|
|
TEST(ConcretePortR8Test, BusPortSetDirection) {
|
|
if (PortDirection::input() == nullptr)
|
|
PortDirection::init();
|
|
ConcreteLibrary lib("r8_lib3", "r8.lib", false);
|
|
lib.setBusBrkts('[', ']');
|
|
ConcreteCell *cell = lib.makeCell("DIR_CELL", true, "");
|
|
ConcretePort *bus = cell->makeBusPort("Q", 3, 0);
|
|
bus->setDirection(PortDirection::output());
|
|
EXPECT_EQ(bus->direction(), PortDirection::output());
|
|
// Check propagation to bits
|
|
ConcretePort *bit0 = bus->findBusBit(0);
|
|
EXPECT_NE(bit0, nullptr);
|
|
EXPECT_EQ(bit0->direction(), PortDirection::output());
|
|
}
|
|
|
|
// ConcreteNetwork: multiple nets and find
|
|
TEST_F(ConcreteNetworkLinkedTest, MultipleNetsFind) {
|
|
Instance *top = network_.topInstance();
|
|
for (int i = 0; i < 10; i++) {
|
|
std::string name = "multi_net_" + std::to_string(i);
|
|
Net *n = network_.makeNet(name.c_str(), top);
|
|
EXPECT_NE(n, nullptr);
|
|
}
|
|
for (int i = 0; i < 10; i++) {
|
|
std::string name = "multi_net_" + std::to_string(i);
|
|
Net *found = network_.findNet(top, name.c_str());
|
|
EXPECT_NE(found, nullptr);
|
|
}
|
|
// Clean up
|
|
for (int i = 0; i < 10; i++) {
|
|
std::string name = "multi_net_" + std::to_string(i);
|
|
Net *n = network_.findNet(top, name.c_str());
|
|
if (n)
|
|
network_.deleteNet(n);
|
|
}
|
|
}
|
|
|
|
// ConcreteNetwork: instance with many children
|
|
TEST_F(ConcreteNetworkLinkedTest, ManyChildren) {
|
|
Instance *top = network_.topInstance();
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
for (int i = 0; i < 5; i++) {
|
|
std::string name = "child_r8_" + std::to_string(i);
|
|
Instance *child = network_.makeInstance(inv_cell, name.c_str(), top);
|
|
EXPECT_NE(child, nullptr);
|
|
}
|
|
InstanceChildIterator *iter = network_.childIterator(top);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_GE(count, 7); // u1, u2, + 5 new
|
|
// Clean up
|
|
for (int i = 0; i < 5; i++) {
|
|
std::string name = "child_r8_" + std::to_string(i);
|
|
Instance *child = network_.findChild(top, name.c_str());
|
|
if (child)
|
|
network_.deleteInstance(child);
|
|
}
|
|
}
|
|
|
|
// ConcreteNetwork: deletePin through disconnect
|
|
TEST_F(ConcreteNetworkLinkedTest, DeletePinPath) {
|
|
Instance *top = network_.topInstance();
|
|
Cell *inv_cell = network_.findCell(lib_, "INV");
|
|
Instance *u_del = network_.makeInstance(inv_cell, "u_del_r8", top);
|
|
Net *del_net = network_.makeNet("del_net_r8", top);
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Pin *pin = network_.connect(u_del, port_a, del_net);
|
|
EXPECT_NE(pin, nullptr);
|
|
|
|
// Disconnect exercises deletePin path
|
|
network_.disconnectPin(pin);
|
|
Pin *found = network_.findPin(u_del, "A");
|
|
// After disconnect, pin should still exist but not connected
|
|
EXPECT_EQ(network_.net(found), nullptr);
|
|
|
|
network_.deleteInstance(u_del);
|
|
network_.deleteNet(del_net);
|
|
}
|
|
|
|
// R8_CheckLibertyCorners removed (segfault - no liberty in simple network)
|
|
|
|
// ConnectedPinIterator1 - uncovered through connectedPinIterator
|
|
TEST_F(ConcreteNetworkLinkedTest, ConnectedPinIteratorMultiPin) {
|
|
// net2_ has u1_y and u2_a connected
|
|
ConnectedPinIterator *iter = network_.connectedPinIterator(pin_u1_y_);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
const Pin *p = iter->next();
|
|
EXPECT_NE(p, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_GE(count, 2); // At least u1_y and u2_a
|
|
}
|
|
|
|
// NetworkNameAdapter: various forwarding methods
|
|
TEST_F(NetworkAdapterTest, AdapterCellName2) {
|
|
const char *name = sdc_net_->name(inv_cell_);
|
|
EXPECT_STREQ(name, "BUF");
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterCellId2) {
|
|
ObjectId aid = sdc_net_->id(inv_cell_);
|
|
ObjectId did = network_.id(inv_cell_);
|
|
EXPECT_EQ(aid, did);
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterCellLibrary2) {
|
|
Library *lib = sdc_net_->library(inv_cell_);
|
|
EXPECT_EQ(lib, lib_);
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterCellIsLeaf2) {
|
|
EXPECT_TRUE(sdc_net_->isLeaf(inv_cell_));
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterInstanceId2) {
|
|
ObjectId aid = sdc_net_->id(u1_);
|
|
ObjectId did = network_.id(u1_);
|
|
EXPECT_EQ(aid, did);
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterInstanceCell2) {
|
|
Cell *cell = sdc_net_->cell(u1_);
|
|
EXPECT_EQ(cell, inv_cell_);
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterInstanceParent2) {
|
|
Instance *parent = sdc_net_->parent(u1_);
|
|
EXPECT_EQ(parent, sdc_net_->topInstance());
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterInstanceIsLeaf2) {
|
|
EXPECT_TRUE(sdc_net_->isLeaf(u1_));
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterPinId2) {
|
|
ObjectId aid = sdc_net_->id(pin_b1_a_);
|
|
ObjectId did = network_.id(pin_b1_a_);
|
|
EXPECT_EQ(aid, did);
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterPinPort2) {
|
|
Port *port = sdc_net_->port(pin_b1_a_);
|
|
EXPECT_EQ(port, port_a_);
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterPinInstance2) {
|
|
Instance *inst = sdc_net_->instance(pin_b1_a_);
|
|
EXPECT_EQ(inst, u1_);
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterPinNet2) {
|
|
Net *net = sdc_net_->net(pin_b1_a_);
|
|
EXPECT_EQ(net, net1_);
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterPinDirection2) {
|
|
PortDirection *dir = sdc_net_->direction(pin_b1_a_);
|
|
EXPECT_TRUE(dir->isInput());
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterPinVertexId2) {
|
|
VertexId vid = sdc_net_->vertexId(pin_b1_a_);
|
|
VertexId dvid = network_.vertexId(pin_b1_a_);
|
|
EXPECT_EQ(vid, dvid);
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterNetId2) {
|
|
ObjectId aid = sdc_net_->id(net1_);
|
|
ObjectId did = network_.id(net1_);
|
|
EXPECT_EQ(aid, did);
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterNetInstance2) {
|
|
Instance *inst = sdc_net_->instance(net1_);
|
|
EXPECT_EQ(inst, sdc_net_->topInstance());
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterNetIsPower2) {
|
|
EXPECT_FALSE(sdc_net_->isPower(net1_));
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterNetIsGround2) {
|
|
EXPECT_FALSE(sdc_net_->isGround(net1_));
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterNetPinIterator2) {
|
|
NetPinIterator *iter = sdc_net_->pinIterator(net1_);
|
|
EXPECT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_GE(count, 1);
|
|
}
|
|
|
|
TEST_F(NetworkAdapterTest, AdapterNetTermIterator2) {
|
|
NetTermIterator *iter = sdc_net_->termIterator(net1_);
|
|
EXPECT_NE(iter, nullptr);
|
|
delete iter;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// R10_ tests for additional network coverage
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// R10_ ConcreteNetwork: Bus port creation and direction setting
|
|
// Covers: BusPort::BusPort, BusPort::setDirection
|
|
TEST_F(ConcreteNetworkLinkedTest, BusPortCreation) {
|
|
// Create bus port on a new cell (not one with existing instances)
|
|
Cell *bus_cell = network_.makeCell(lib_, "BUS_TEST", true, "test.lib");
|
|
Port *bus = network_.makeBusPort(bus_cell, "bus_data", 0, 7);
|
|
ASSERT_NE(bus, nullptr);
|
|
EXPECT_TRUE(network_.isBus(bus));
|
|
EXPECT_EQ(network_.size(bus), 8);
|
|
network_.setDirection(bus, PortDirection::input());
|
|
EXPECT_TRUE(network_.direction(bus)->isInput());
|
|
// Check bus members
|
|
EXPECT_TRUE(network_.hasMembers(bus));
|
|
Port *bit0 = network_.findMember(bus, 0);
|
|
EXPECT_NE(bit0, nullptr);
|
|
}
|
|
|
|
// R10_ ConcreteNetwork: multiple clear operations
|
|
// Covers: ConcreteNetwork clear paths
|
|
TEST_F(ConcreteNetworkLinkedTest, ClearAndRebuild) {
|
|
// Verify we can query before clear
|
|
Instance *top = network_.topInstance();
|
|
EXPECT_NE(top, nullptr);
|
|
// The fixture will clear in TearDown; this verifies basic integrity
|
|
EXPECT_NE(network_.findChild(top, "u1"), nullptr);
|
|
}
|
|
|
|
// R10_ ConcreteInstance: cell() accessor
|
|
// Covers: ConcreteInstance::cell() const
|
|
TEST_F(ConcreteNetworkLinkedTest, InstanceCellAccessor) {
|
|
Cell *cell = network_.cell(u1_);
|
|
ASSERT_NE(cell, nullptr);
|
|
EXPECT_STREQ(network_.name(cell), "INV");
|
|
// Also test on top instance
|
|
Cell *top_cell = network_.cell(network_.topInstance());
|
|
ASSERT_NE(top_cell, nullptr);
|
|
EXPECT_STREQ(network_.name(top_cell), "TOP");
|
|
}
|
|
|
|
// R10_ ConcreteInstance: findChild via network interface
|
|
// Covers: ConcreteInstance::findChild(const char*) const
|
|
TEST_F(ConcreteNetworkLinkedTest, FindChildExhaustive) {
|
|
Instance *top = network_.topInstance();
|
|
Instance *c1 = network_.findChild(top, "u1");
|
|
Instance *c2 = network_.findChild(top, "u2");
|
|
EXPECT_EQ(c1, u1_);
|
|
EXPECT_EQ(c2, u2_);
|
|
Instance *c3 = network_.findChild(top, "nonexistent");
|
|
EXPECT_EQ(c3, nullptr);
|
|
// Leaf instances have no children
|
|
Instance *c4 = network_.findChild(u1_, "any");
|
|
EXPECT_EQ(c4, nullptr);
|
|
}
|
|
|
|
// R10_ ConcreteInstance: findPin(Port*) via network interface
|
|
// Covers: ConcreteInstance::findPin(Port const*) const
|
|
TEST_F(ConcreteNetworkLinkedTest, FindPinByPort4) {
|
|
Cell *inv_cell = network_.cell(u1_);
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Port *port_y = network_.findPort(inv_cell, "Y");
|
|
ASSERT_NE(port_a, nullptr);
|
|
ASSERT_NE(port_y, nullptr);
|
|
|
|
Pin *p_a = network_.findPin(u1_, port_a);
|
|
Pin *p_y = network_.findPin(u1_, port_y);
|
|
EXPECT_EQ(p_a, pin_u1_a_);
|
|
EXPECT_EQ(p_y, pin_u1_y_);
|
|
}
|
|
|
|
// R10_ ConcreteInstance: deleteChild then verify
|
|
// Covers: ConcreteInstance::deleteChild(ConcreteInstance*)
|
|
TEST_F(ConcreteNetworkLinkedTest, DeleteChildAndVerify) {
|
|
Instance *top = network_.topInstance();
|
|
Cell *inv_cell = network_.cell(u1_);
|
|
Instance *extra = network_.makeInstance(inv_cell, "extra", top);
|
|
ASSERT_NE(extra, nullptr);
|
|
|
|
// Verify it exists
|
|
Instance *found = network_.findChild(top, "extra");
|
|
EXPECT_EQ(found, extra);
|
|
|
|
// Delete it
|
|
network_.deleteInstance(extra);
|
|
|
|
// Verify it's gone
|
|
found = network_.findChild(top, "extra");
|
|
EXPECT_EQ(found, nullptr);
|
|
}
|
|
|
|
// R10_ ConcreteInstance: addNet and deleteNet
|
|
// Covers: ConcreteInstance::addNet, ConcreteInstance::deleteNet, ConcreteNet::~ConcreteNet
|
|
TEST_F(ConcreteNetworkLinkedTest, AddDeleteNetExhaustive) {
|
|
Instance *top = network_.topInstance();
|
|
Net *n4 = network_.makeNet("n4", top);
|
|
ASSERT_NE(n4, nullptr);
|
|
|
|
// Verify the net exists
|
|
Net *found = network_.findNet(top, "n4");
|
|
EXPECT_EQ(found, n4);
|
|
|
|
// Delete the net
|
|
network_.deleteNet(n4);
|
|
|
|
// Verify it's gone
|
|
found = network_.findNet(top, "n4");
|
|
EXPECT_EQ(found, nullptr);
|
|
}
|
|
|
|
// R10_ ConcreteInstance: setCell
|
|
// Covers: ConcreteInstance::setCell(ConcreteCell*)
|
|
TEST_F(ConcreteNetworkLinkedTest, SetCellOnInstance) {
|
|
// Create a second cell type
|
|
Cell *buf_cell = network_.makeCell(lib_, "BUF2", true, "test.lib");
|
|
network_.makePort(buf_cell, "A");
|
|
network_.makePort(buf_cell, "Y");
|
|
network_.setDirection(network_.findPort(buf_cell, "A"), PortDirection::input());
|
|
network_.setDirection(network_.findPort(buf_cell, "Y"), PortDirection::output());
|
|
|
|
// Replace cell of u1
|
|
network_.replaceCell(u1_, buf_cell);
|
|
Cell *new_cell = network_.cell(u1_);
|
|
EXPECT_STREQ(network_.name(new_cell), "BUF2");
|
|
}
|
|
|
|
// R10_ ConcretePin: port name via port accessor
|
|
// Covers: ConcretePin internal paths
|
|
TEST_F(ConcreteNetworkLinkedTest, PinPortName2) {
|
|
Port *port = network_.port(pin_u1_a_);
|
|
ASSERT_NE(port, nullptr);
|
|
const char *name = network_.name(port);
|
|
EXPECT_STREQ(name, "A");
|
|
}
|
|
|
|
// R10_ ConcretePin: setVertexId
|
|
// Covers: ConcretePin::setVertexId(unsigned int)
|
|
TEST_F(ConcreteNetworkLinkedTest, PinSetVertexIdMultiple2) {
|
|
network_.setVertexId(pin_u1_a_, 100);
|
|
EXPECT_EQ(network_.vertexId(pin_u1_a_), 100u);
|
|
network_.setVertexId(pin_u1_a_, 200);
|
|
EXPECT_EQ(network_.vertexId(pin_u1_a_), 200u);
|
|
network_.setVertexId(pin_u1_a_, 0);
|
|
EXPECT_EQ(network_.vertexId(pin_u1_a_), 0u);
|
|
}
|
|
|
|
// R10_ ConcreteNet: pin iteration and manipulation
|
|
// Covers: ConcreteNet::addPin, ConcreteNetPinIterator ctor
|
|
TEST_F(ConcreteNetworkLinkedTest, NetPinIteration) {
|
|
// net2_ connects u1.Y and u2.A
|
|
NetPinIterator *iter = network_.pinIterator(net2_);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
const Pin *pin = iter->next();
|
|
EXPECT_NE(pin, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 2); // u1.Y and u2.A
|
|
}
|
|
|
|
// R10_ ConcreteNet: term iteration
|
|
// Covers: ConcreteNet::addTerm, ConcreteNetTermIterator ctor
|
|
TEST_F(ConcreteNetworkLinkedTest, NetTermIteration) {
|
|
// Leaf-level nets don't have terms, but let's verify the iterator works
|
|
NetTermIterator *iter = network_.termIterator(net1_);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
iter->next();
|
|
count++;
|
|
}
|
|
delete iter;
|
|
// Terms exist on top-level ports connected to nets
|
|
EXPECT_GE(count, 0);
|
|
}
|
|
|
|
// R10_ Iterators: library iterator
|
|
// Covers: ConcreteLibraryIterator1 ctor
|
|
TEST_F(ConcreteNetworkLinkedTest, LibraryIteratorMultiple) {
|
|
// Create a second library
|
|
Library *lib2 = network_.makeLibrary("test_lib2", "test2.lib");
|
|
ASSERT_NE(lib2, nullptr);
|
|
|
|
LibraryIterator *iter = network_.libraryIterator();
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
Library *lib = iter->next();
|
|
EXPECT_NE(lib, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_GE(count, 2);
|
|
}
|
|
|
|
// R10_ Iterators: liberty library iterator
|
|
// Covers: ConcreteLibertyLibraryIterator ctor/dtor
|
|
TEST_F(ConcreteNetworkLinkedTest, LibertyLibraryIterator2) {
|
|
LibertyLibraryIterator *iter = network_.libertyLibraryIterator();
|
|
ASSERT_NE(iter, nullptr);
|
|
// No liberty libs in this test fixture
|
|
EXPECT_FALSE(iter->hasNext());
|
|
delete iter;
|
|
}
|
|
|
|
// R10_ Iterators: cell port iterator
|
|
// Covers: ConcreteCellPortIterator1 ctor
|
|
TEST_F(ConcreteNetworkLinkedTest, CellPortIteratorOnTopCell) {
|
|
Cell *top_cell = network_.cell(network_.topInstance());
|
|
CellPortIterator *iter = network_.portIterator(top_cell);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
Port *port = iter->next();
|
|
EXPECT_NE(port, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 3); // clk, data_in, data_out
|
|
}
|
|
|
|
// R10_ Iterators: cell port bit iterator
|
|
// Covers: ConcreteCellPortBitIterator ctor, ConcreteCellPortBitIterator1 ctor
|
|
TEST_F(ConcreteNetworkLinkedTest, CellPortBitIteratorOnTopCell) {
|
|
Cell *top_cell = network_.cell(network_.topInstance());
|
|
CellPortBitIterator *iter = network_.portBitIterator(top_cell);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
Port *port = iter->next();
|
|
EXPECT_NE(port, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 3);
|
|
}
|
|
|
|
// R10_ Iterators: instance child iterator
|
|
// Covers: ConcreteInstanceChildIterator ctor
|
|
TEST_F(ConcreteNetworkLinkedTest, InstanceChildIteratorCount) {
|
|
Instance *top = network_.topInstance();
|
|
InstanceChildIterator *iter = network_.childIterator(top);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
Instance *child = iter->next();
|
|
EXPECT_NE(child, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 2);
|
|
}
|
|
|
|
// R10_ Iterators: instance pin iterator
|
|
// Covers: ConcreteInstancePinIterator ctor
|
|
TEST_F(ConcreteNetworkLinkedTest, InstancePinIteratorOnU2) {
|
|
InstancePinIterator *iter = network_.pinIterator(u2_);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
Pin *pin = iter->next();
|
|
EXPECT_NE(pin, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 2); // A, Y
|
|
}
|
|
|
|
// R10_ Iterators: port member iterator (for bus port)
|
|
// Covers: ConcretePortMemberIterator1 ctor
|
|
TEST_F(ConcreteNetworkLinkedTest, PortMemberIterator) {
|
|
// Create on a new cell to avoid instance pin mismatch
|
|
Cell *bus_cell2 = network_.makeCell(lib_, "BUS_TEST2", true, "test.lib");
|
|
Port *bus = network_.makeBusPort(bus_cell2, "test_bus", 0, 3);
|
|
ASSERT_NE(bus, nullptr);
|
|
|
|
PortMemberIterator *iter = network_.memberIterator(bus);
|
|
ASSERT_NE(iter, nullptr);
|
|
int count = 0;
|
|
while (iter->hasNext()) {
|
|
Port *member = iter->next();
|
|
EXPECT_NE(member, nullptr);
|
|
count++;
|
|
}
|
|
delete iter;
|
|
EXPECT_EQ(count, 4); // bits 0..3
|
|
}
|
|
|
|
// R10_ Network: hasMembers for scalar port
|
|
// Covers: Network::hasMembers(Port const*) const
|
|
TEST_F(ConcreteNetworkLinkedTest, HasMembersScalar2) {
|
|
Cell *inv_cell = network_.cell(u1_);
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
EXPECT_FALSE(network_.hasMembers(port_a));
|
|
}
|
|
|
|
// R10_ Network: findPinLinear
|
|
// Covers: Network::findPinLinear(Instance const*, char const*) const
|
|
TEST_F(ConcreteNetworkLinkedTest, FindPinLinear2) {
|
|
Pin *pin = network_.findPin(u1_, "A");
|
|
EXPECT_EQ(pin, pin_u1_a_);
|
|
Pin *null_pin = network_.findPin(u1_, "nonexistent");
|
|
EXPECT_EQ(null_pin, nullptr);
|
|
}
|
|
|
|
// R10_ Network: findNetLinear
|
|
// Covers: Network::findNetLinear(Instance const*, char const*) const
|
|
TEST_F(ConcreteNetworkLinkedTest, FindNetByNameLinear) {
|
|
Instance *top = network_.topInstance();
|
|
Net *net = network_.findNet(top, "n1");
|
|
EXPECT_EQ(net, net1_);
|
|
Net *null_net = network_.findNet(top, "nonexistent_net");
|
|
EXPECT_EQ(null_net, nullptr);
|
|
}
|
|
|
|
// R10_ Network: findNetsMatchingLinear with wildcard
|
|
// Covers: Network::findNetsMatchingLinear(Instance const*, PatternMatch const*) const
|
|
TEST_F(ConcreteNetworkLinkedTest, FindNetsMatchingWildcard) {
|
|
Instance *top = network_.topInstance();
|
|
PatternMatch pattern("n*");
|
|
NetSeq matches;
|
|
network_.findNetsMatching(top, &pattern, matches);
|
|
EXPECT_EQ(matches.size(), 3u); // n1, n2, n3
|
|
}
|
|
|
|
// R10_ Network: findNetsMatchingLinear with exact match
|
|
TEST_F(ConcreteNetworkLinkedTest, FindNetsMatchingExact) {
|
|
Instance *top = network_.topInstance();
|
|
PatternMatch pattern("n2");
|
|
NetSeq matches;
|
|
network_.findNetsMatching(top, &pattern, matches);
|
|
EXPECT_EQ(matches.size(), 1u);
|
|
}
|
|
|
|
// R10_ NetworkEdit: connectPin(Pin*, Net*)
|
|
// Covers: NetworkEdit::connectPin(Pin*, Net*)
|
|
TEST_F(ConcreteNetworkLinkedTest, ConnectPinReconnect) {
|
|
// Disconnect pin_u1_a_ from net1_ and reconnect to net3_
|
|
network_.disconnectPin(pin_u1_a_);
|
|
Pin *reconnected = network_.connect(u1_,
|
|
network_.findPort(network_.cell(u1_), "A"), net3_);
|
|
ASSERT_NE(reconnected, nullptr);
|
|
EXPECT_EQ(network_.net(reconnected), net3_);
|
|
}
|
|
|
|
// R10_ NetworkEdit: disconnect and verify iteration
|
|
TEST_F(ConcreteNetworkLinkedTest, DisconnectPinVerifyNet) {
|
|
// Count pins on net2_ before disconnect
|
|
NetPinIterator *iter = network_.pinIterator(net2_);
|
|
int before_count = 0;
|
|
while (iter->hasNext()) { iter->next(); before_count++; }
|
|
delete iter;
|
|
EXPECT_EQ(before_count, 2);
|
|
|
|
// Disconnect u2.A from net2
|
|
network_.disconnectPin(pin_u2_a_);
|
|
|
|
// Count after
|
|
iter = network_.pinIterator(net2_);
|
|
int after_count = 0;
|
|
while (iter->hasNext()) { iter->next(); after_count++; }
|
|
delete iter;
|
|
EXPECT_EQ(after_count, 1);
|
|
}
|
|
|
|
// R10_ NetworkAdapter: hasMembers forwarding on scalar port
|
|
// Covers: NetworkNameAdapter hasMembers path
|
|
TEST_F(NetworkAdapterTest, AdapterHasMembersScalar) {
|
|
EXPECT_FALSE(sdc_net_->hasMembers(port_a_));
|
|
EXPECT_FALSE(sdc_net_->isBus(port_a_));
|
|
EXPECT_FALSE(sdc_net_->isBundle(port_a_));
|
|
}
|
|
|
|
// R10_ NetworkAdapter: port size forwarding
|
|
// Covers: NetworkNameAdapter size path
|
|
TEST_F(NetworkAdapterTest, AdapterPortSize2) {
|
|
int size = sdc_net_->size(port_a_);
|
|
EXPECT_EQ(size, 1); // Scalar port has size 1
|
|
}
|
|
|
|
// R10_ NetworkAdapter: name(Port) forwarding
|
|
// Covers: NetworkNameAdapter::name(Port const*) const
|
|
TEST_F(NetworkAdapterTest, AdapterPortName3) {
|
|
const char *name = sdc_net_->name(port_a_);
|
|
EXPECT_STREQ(name, "A");
|
|
}
|
|
|
|
// R10_ NetworkAdapter: busName forwarding
|
|
// Covers: NetworkNameAdapter::busName(Port const*) const
|
|
TEST_F(NetworkAdapterTest, AdapterBusName) {
|
|
const char *name = sdc_net_->busName(port_a_);
|
|
// Scalar port busName may be nullptr or same as port name
|
|
if (name != nullptr) {
|
|
EXPECT_STREQ(name, "A");
|
|
}
|
|
}
|
|
|
|
// R10_ NetworkAdapter: makeNet forwarding
|
|
// Covers: NetworkNameAdapter::makeNet(char const*, Instance*)
|
|
TEST_F(NetworkAdapterTest, AdapterMakeNet3) {
|
|
Instance *top = sdc_net_->topInstance();
|
|
Net *net = sdc_net_->makeNet("adapter_net", top);
|
|
ASSERT_NE(net, nullptr);
|
|
Net *found = sdc_net_->findNet(top, "adapter_net");
|
|
EXPECT_EQ(found, net);
|
|
}
|
|
|
|
// R10_ NetworkAdapter: findPort forwarding
|
|
// Covers: NetworkNameAdapter::findPort(Cell const*, char const*) const
|
|
TEST_F(NetworkAdapterTest, AdapterFindPortByName2) {
|
|
Port *found = sdc_net_->findPort(inv_cell_, "A");
|
|
EXPECT_EQ(found, port_a_);
|
|
Port *not_found = sdc_net_->findPort(inv_cell_, "nonexistent");
|
|
EXPECT_EQ(not_found, nullptr);
|
|
}
|
|
|
|
// R10_ NetworkAdapter: findPortsMatching forwarding
|
|
// Covers: NetworkNameAdapter::findPortsMatching(Cell const*, PatternMatch const*) const
|
|
TEST_F(NetworkAdapterTest, AdapterFindPortsMatchingWild) {
|
|
PatternMatch pattern("*");
|
|
PortSeq ports = sdc_net_->findPortsMatching(inv_cell_, &pattern);
|
|
EXPECT_EQ(ports.size(), 2u); // A, Y
|
|
}
|
|
|
|
// R10_ NetworkAdapter: findPin(Instance, Port) forwarding
|
|
// Covers: NetworkNameAdapter::findPin(Instance const*, Port const*) const
|
|
TEST_F(NetworkAdapterTest, AdapterFindPinByPort2) {
|
|
Pin *pin = sdc_net_->findPin(u1_, port_a_);
|
|
EXPECT_EQ(pin, pin_b1_a_);
|
|
}
|
|
|
|
// R10_ ConcreteNetwork: merge nets exercise
|
|
// Covers: ConcreteNet pin/term manipulation, mergeInto
|
|
TEST_F(ConcreteNetworkLinkedTest, MergeNetsAndVerify) {
|
|
Instance *top = network_.topInstance();
|
|
Net *merge_src = network_.makeNet("merge_src", top);
|
|
Net *merge_dst = network_.makeNet("merge_dst", top);
|
|
ASSERT_NE(merge_src, nullptr);
|
|
ASSERT_NE(merge_dst, nullptr);
|
|
|
|
// Connect a pin to source net
|
|
Cell *inv_cell = network_.cell(u1_);
|
|
Instance *extra = network_.makeInstance(inv_cell, "merge_inst", top);
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
network_.connect(extra, port_a, merge_src);
|
|
|
|
// Merge src into dst
|
|
network_.mergeInto(merge_src, merge_dst);
|
|
|
|
// Verify merged
|
|
Net *merged = network_.mergedInto(merge_src);
|
|
EXPECT_EQ(merged, merge_dst);
|
|
|
|
network_.deleteInstance(extra);
|
|
}
|
|
|
|
// R10_ ConcreteInstance: initPins explicit exercise
|
|
// Covers: ConcreteInstance::initPins
|
|
TEST_F(ConcreteNetworkLinkedTest, InitPinsExercise2) {
|
|
// makeInstance already calls initPins, but let's create a new instance
|
|
// and verify pins are initialized properly
|
|
Instance *top = network_.topInstance();
|
|
Cell *inv_cell = network_.cell(u1_);
|
|
Instance *new_inst = network_.makeInstance(inv_cell, "init_test", top);
|
|
ASSERT_NE(new_inst, nullptr);
|
|
|
|
// Pins should be initialized (nullptr but accessible)
|
|
Pin *pin = network_.findPin(new_inst, "A");
|
|
EXPECT_EQ(pin, nullptr); // Not connected yet
|
|
|
|
// Connect and verify
|
|
Pin *connected = network_.connect(new_inst,
|
|
network_.findPort(inv_cell, "A"), net1_);
|
|
EXPECT_NE(connected, nullptr);
|
|
EXPECT_EQ(network_.net(connected), net1_);
|
|
|
|
network_.deleteInstance(new_inst);
|
|
}
|
|
|
|
// R10_ ConcreteInstance: disconnect pin exercises internal paths
|
|
// Covers: disconnect/connect paths for pins
|
|
TEST_F(ConcreteNetworkLinkedTest, DisconnectPinExercise) {
|
|
Instance *top = network_.topInstance();
|
|
Cell *inv_cell = network_.cell(u1_);
|
|
Instance *dp_inst = network_.makeInstance(inv_cell, "dp_test", top);
|
|
Port *port_a = network_.findPort(inv_cell, "A");
|
|
Pin *dp_pin = network_.connect(dp_inst, port_a, net1_);
|
|
EXPECT_NE(dp_pin, nullptr);
|
|
EXPECT_EQ(network_.net(dp_pin), net1_);
|
|
|
|
// Disconnect removes pin from net
|
|
network_.disconnectPin(dp_pin);
|
|
// After disconnect, the pin's net should be nullptr
|
|
EXPECT_EQ(network_.net(dp_pin), nullptr);
|
|
|
|
network_.deleteInstance(dp_inst);
|
|
}
|
|
|
|
// R10_ Network: multiple libraries and find
|
|
TEST_F(ConcreteNetworkLinkedTest, MultipleCellsAndFind) {
|
|
// Create cells in a new library
|
|
Library *lib2 = network_.makeLibrary("other_lib", "other.lib");
|
|
Cell *nand = network_.makeCell(lib2, "NAND2", true, "other.lib");
|
|
network_.makePort(nand, "A");
|
|
network_.makePort(nand, "B");
|
|
network_.makePort(nand, "Y");
|
|
|
|
// Find the cell
|
|
Cell *found = network_.findCell(lib2, "NAND2");
|
|
EXPECT_EQ(found, nand);
|
|
Cell *not_found = network_.findCell(lib2, "nonexistent");
|
|
EXPECT_EQ(not_found, nullptr);
|
|
}
|
|
|
|
// R10_ ConcreteNetwork: findPin across multiple instances
|
|
TEST_F(ConcreteNetworkLinkedTest, FindPinAllInstances) {
|
|
// Check all instances
|
|
Pin *u1a = network_.findPin(u1_, "A");
|
|
Pin *u1y = network_.findPin(u1_, "Y");
|
|
Pin *u2a = network_.findPin(u2_, "A");
|
|
Pin *u2y = network_.findPin(u2_, "Y");
|
|
EXPECT_EQ(u1a, pin_u1_a_);
|
|
EXPECT_EQ(u1y, pin_u1_y_);
|
|
EXPECT_EQ(u2a, pin_u2_a_);
|
|
EXPECT_EQ(u2y, pin_u2_y_);
|
|
}
|
|
|
|
} // namespace sta
|