Interesting challenge- thanks for posting it.
The first thing I'd mention is that deleteBufferTree -selNet isn't precisely limited to the list of nets it is supplied with. For example, in this netlist, there are 2 buffers in series before the register:
module testcase(in1, in2);
input in1, in2;
wire net1;
BUFX1 i0(.A(in1), .Y(net1));
BUFX1 i1(.A(net1), .Y(net2));
DFFX1 i2(.D(net2));
endmodule
If you called deleteBufferTree -selNet and supplied it with only "in1" as the net, both buffers would be deleted because deleteBufferTree traverses and tries to delete all the buffers (and inverter pairs) in the tree of the net name you supply.
Because of this, the requirement about limiting the removal to only the buffers with a fanout of 1 is a little trickier than it might otherwise appear. You might get a good ways towards where you're trying to get if you call deleteBufferTree -selNet with a file containing all the nets connected to IOs. You could capture that list of nets like this:
set outfile [open sel.net "w"]
foreach net [dbGet -u top.terms.net.name] {
puts $outfile "$net"
}
close $outfile
Then you could call deleteBufferTree -selNet sel.net and it would delete all of the buffer trees that are connected to IOs.
If you truly needed to restrict this to nets with a fanout of 1 you'd need to do something more sophisticated where you examine the fanout tree prior to including the IO net to make sure the fanout of each net downstream from the IO net is a buffer or inverter pair and has a fanout of 1.
Let me know what you think of this so far and we can continue our discussion.
Hope this helps,
Bob