code: def probe(w, name=None):
      
      if not isinstance(w, WireVector):
          raise PyrtlError('Only WireVectors can be probed')
  
      if name is None:
          name = '(%s: %s)' % (probeIndexer.make_valid_string(), w.name)
      print("Probe: " + name + ' ' + get_stack(w))
  
      p = Output(name=name)
      p <<= w  # late assigns len from w automatically
      return w
docs: Print useful information about a WireVector when in debug mode.
  
      :param w: WireVector from which to get info
      :param name: optional name for probe (defaults to an autogenerated name)
      :return: original WireVector w
  
      Probe can be inserted into a existing design easily as it returns the
      original wire unmodified. For example ``y <<= x[0:3] + 4`` could be turned
      into ``y <<= probe(x)[0:3] + 4`` to give visibility into both the origin of
      ``x`` (including the line that WireVector was originally created) and
      the run-time values of ``x`` (which will be named and thus show up by
      default in a trace.  Likewise ``y <<= probe(x[0:3]) + 4``,
      ``y <<= probe(x[0:3] + 4)``, and ``probe(y) <<= x[0:3] + 4`` are all
      valid uses of `probe`.
  
      Note: `probe` does actually add a wire to the working block of w (which can
      confuse various post-processing transforms such as output to verilog).