#include #include #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(inv_cell_)); EXPECT_EQ(lc, nullptr); } // NetworkNameAdapter: cell(LibertyCell*) forwarding TEST_F(NetworkAdapterTest, AdapterCellFromLibertyCell) { Cell *c = sdc_net_->cell(static_cast(nullptr)); EXPECT_EQ(c, nullptr); } // NetworkNameAdapter: cell(const LibertyCell*) forwarding TEST_F(NetworkAdapterTest, AdapterCellFromConstLibertyCell) { const Cell *c = sdc_net_->cell(static_cast(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(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