Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ your own tool).
- **Trace to Driver**: the whole combinational fan-in cone of a pin, back
to flip-flops and ports. Overlay several traces: each gets its own color,
shared wires are striped and shared gates outlined.
- **Grow the schematic by hand**: click an open pin to add its net,
double-click a box to show all of its pins.
- **Grow the schematic by hand**: start from any instance (right-click it
in the design tree, then Show in Schematic), click an open pin to add its
net, double-click a box to show all of its pins.
- **Design tree**, loaded lazily so large netlists open fast: instances,
ports, nets and bus bits.
- **Show Sources**: where an instance, pin or net is declared and, for
Expand Down
13 changes: 13 additions & 0 deletions src/NetlistTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,12 @@ void NetlistTreeNode::render() {
}
} else if (isInstanceNode()) {
if (ImGui::BeginPopupContextItem()) {
// The top design has no box of its own to draw.
if (!isRoot()) {
bool clicked = ImGui::MenuItem("Show in Schematic (replace view)");
viewModeTooltip(true);
if (clicked) getTree()->sendShowInstance(getInstancePath());
}
json req;
req["kind"] = "instance";
writePath(req, getInstancePath());
Expand Down Expand Up @@ -680,6 +686,13 @@ void NetlistTree::sendLoadEquipotential(const NetlistTree::Path& path, const Ter
ws_->send(req.dump());
}

void NetlistTree::sendShowInstance(const InstancePath& path) const {
json req;
req["request"] = "resolve_instance";
writePath(req, path);
ws_->send(req.dump());
}

void NetlistTree::sendTraceDriver(const NetlistTree::Path& path, unsigned termChildID,
const std::vector<int>& bits, const std::string& label,
bool clearView) const {
Expand Down
4 changes: 4 additions & 0 deletions src/NetlistTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ class NetlistTree {
void sendTraceDriver(const Path& path, unsigned termChildID,
const std::vector<int>& bits, const std::string& label,
bool clearView = true) const;
// Asks the provider to resolve the instance at `path`; its
// instance_resolved reply redraws the schematic with that instance
// alone, every pin open (same as a host focus_instance push).
void sendShowInstance(const InstancePath& path) const;
INetlistProvider* getProvider() const { return ws_; }

// Called before every tree-initiated equipotential request.
Expand Down
14 changes: 14 additions & 0 deletions tests/NetlistTreeTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,20 @@ TEST(NetlistTree, SendLoadEquipotentialCanKeepTheView) {
TraceStore::clear();
}

// "Show in Schematic": resolve_instance by ids and names; the reply draws it.
TEST(NetlistTree, SendShowInstanceRequestsResolveInstance) {
FakeNetlistProvider provider;
NetlistTree tree(&provider);

tree.sendShowInstance(InstancePath{{1, "u1"}, {4, ""}});

ASSERT_EQ(provider.sent.size(), 1u);
auto req = nlohmann::json::parse(provider.sent[0]);
EXPECT_EQ(req["request"], "resolve_instance");
EXPECT_EQ(req["id_path"], (std::vector<unsigned>{1, 4}));
EXPECT_EQ(req["path"], (std::vector<std::string>{"u1", ""}));
}

TEST(NetlistTree, SendTraceDriverFormatsScalarRequestAndFiresCallback) {
FakeNetlistProvider provider;
NetlistTree tree(&provider);
Expand Down
8 changes: 4 additions & 4 deletions tests/SelectionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,12 +331,12 @@ TEST_F(TreeReveal, ContextMenuClickDoesNotSelectTheRowUnderIt) {
provider.sent.clear();

click(at(4, 60.f), ImGuiMouseButton_Right); // u0's context menu
// Its first entry ("Show Properties") lies over the next row, u1's.
// Its first entry ("Show in Schematic") lies over the next row, u1's.
click(ImVec2(at(4, 60.f).x + 30.f, at(5, 0.f).y), ImGuiMouseButton_Left);

auto props = take("get_properties");
ASSERT_EQ(props.size(), 1u);
EXPECT_EQ(props[0]["id_path"], nlohmann::json::array({0})); // u0's
auto resolve = take("resolve_instance");
ASSERT_EQ(resolve.size(), 1u);
EXPECT_EQ(resolve[0]["id_path"], nlohmann::json::array({0})); // u0's
EXPECT_FALSE(SelectionStore::isSelected(InstancePath{{1, "u1"}}));
EXPECT_FALSE(SelectionStore::isSelected(InstancePath{{2, "u2"}}));

Expand Down
Loading