I think the following code example (although not DFS) should contain all the relevant idiomatic Yosys code snippets that you'd need:
// create canonical versions of all sigbits
SigMap sigmap(module);
// first layer of bits
pool<SigBit> input_bits;
for (auto wire : module->wires())
if (wire->port_input)
for (auto bit : sigmap(wire))
input_bits.insert(bit);
// index: from sigbit to driven cells
dict<SigBit, pool<Cell*>> bit2cells;
// index: from cell to driven sigbits
dict<Cell*, pool<SigBit>> cell2bits;
for (auto cell : module->cells())
for (auto &conn : cell->connections()) {
if (cell->input(conn.first)) {
for (auto bit : sigmap(conn.second))
bit2cells[bit].insert(cell);
}
if (cell->output(conn.first)) {
for (auto bit : sigmap(conn.second))
cell2bits[cell].insert(bit);
}
}
pool<SigBit> queue = input_bits;
pool<Cell*> visited_cells;
while (!queue.empty())
{
log("------\n");
pool<Cell*> this_iter_cells;
for (auto bit : queue)
for (auto cell : bit2cells[bit])
if (!visited_cells.count(cell)) {
log(" %s\n", log_id(cell));
visited_cells.insert(cell);
this_iter_cells.insert(cell);
}
queue.clear();
for (auto cell : this_iter_cells)
for (auto bit : cell2bits[cell])
queue.insert(bit);
}
The most important things to take away from that:
Use SigMap
to create canonical representations of signal bits (in case two wires are connected to each other and are just "alias names" for the same actual bit).
Break up your algorithm in two stages: (1) create the index structures that you need and (2) perform the actual algorithm.
You might also find the answers to this and this question useful.
(I'm writing this answer in a hurry.. Please ask further questions in comments below if anything is unclear.)