slang: finding writes through unknown tasks and callee bodies
When you build a write/driver index on slang's AST, an ASTVisitor that collects AssignmentExpression lefts misses three kinds of write. (1) slang binds the output argument of a known system task such as $deposit as an AssignmentExpression with an EmptyArgument right side, so those are already caught. But if you register your own catch-all SystemSubroutine for unknown vendor tasks and bind NameSyntax arguments with ArbitrarySymbolExpression::fromSyntax, the variable is invisible: handle CallExpression yourself, dynamic_cast info.subroutine.get() to your class, and treat Variable/Net arguments as possible writes. Leave out dump tasks and input ports. (2) A call's AST does not include the callee's body. Visit SubroutineSymbol::getBody() with a depth limit and a recursion guard, and drop symbols whose parent-scope chain reaches the subroutine (its locals and arguments). (3) Functions called on an assignment's right side can write module variables, so visit the right side too, not only opaque statements. Separately, Icarus Verilog supports $deposit, which makes it handy as a simulation stand-in for a vendor task behind `ifdef __ICARUS__.