def specs_to_table_string(specs_to_be_shown)
      whitespace_padding = 3
      table = []
      attrs_to_be_shown = {
        name:        SpecTableAttr.new('Name',      true,  'Name'.length + whitespace_padding),
        symbol:      SpecTableAttr.new('Symbol',    false, 'Symbol'.length + whitespace_padding),
        mode:        SpecTableAttr.new('Mode',      true,  'Mode'.length + whitespace_padding),
        type:        SpecTableAttr.new('Type',      true,  'Type'.length + whitespace_padding),
        sub_type:    SpecTableAttr.new('Sub-Type',  false, 'Sub-Type'.length + whitespace_padding),
        # spec SpecTableAttribute :description is called parameter in the spec table output to match historical docs
        description: SpecTableAttr.new('Parameter', false, 'Parameter'.length + whitespace_padding),
        min:         SpecTableAttr.new('Min',       false, 'Min'.length + whitespace_padding),
        typ:         SpecTableAttr.new('Typ',       false, 'Typ'.length + whitespace_padding),
        max:         SpecTableAttr.new('Max',       false, 'Max'.length + whitespace_padding),
        unit:        SpecTableAttr.new('Unit',      false, 'Unit'.length + whitespace_padding),
        audience:    SpecTableAttr.new('Audience',  false, 'Audience'.length + whitespace_padding)
        # notes:       SpecTableAttr.new('Notes',     false, 'Notes'.length + whitespace_padding)
      }
      # Calculate the padding needed in the spec table for the longest attr of all specs
      specs_to_be_shown.each do |spec|
        attrs_to_be_shown.each do |attr_name, attr_struct|
          unless spec.send(attr_name).nil?
            if spec.send(attr_name).class == Origen::Specs::Spec::Limit
              next if spec.send(attr_name).value.nil?
              current_padding = spec.send(attr_name).value.to_s.length + whitespace_padding
            else
              current_padding = spec.send(attr_name).to_s.length + whitespace_padding
            end
            attr_struct.padding = current_padding if attr_struct.padding < current_padding
            attr_struct.show = true # We found real data for this attr on at least one spec so show it in the spec table
          end
        end
      end
      # Now that each spec attribute padding construct the spec table header
      header = ''
      attrs_to_be_shown.each do |_attr_name, attr_struct|
        next if attr_struct.show == false
        header += "| #{attr_struct.table_text}".ljust(attr_struct.padding)
      end
      header += '|'
      ip_header = "| IP: #{specs_to_be_shown.first.ip_name} ".ljust(header.length - 1)
      ip_header += '|'
      table << '=' * header.length
      table << ip_header
      table << '=' * header.length
      table << header
      table << '-' * header.length
      # Create the data lines in the spec table
      specs_to_be_shown.each do |spec|
        data = ''
        attrs_to_be_shown.each do |attr_name, attr_struct|
          next if attr_struct.show == false
          if spec.send(attr_name).class == Origen::Specs::Spec::Limit
            data += "| #{spec.send(attr_name).value}".ljust(attr_struct.padding)
          else
            data += "| #{spec.send(attr_name)}".ljust(attr_struct.padding)
          end
        end
        table << data += '|'
      end
      table << '-' * header.length
      table.flatten.join("\n")
    end
def specs_to_table_string(specs_to_be_shown)
      whitespace_padding = 3
      table = []
      attrs_to_be_shown = {
        name:        SpecTableAttr.new('Name',      true,  'Name'.length + whitespace_padding),
        symbol:      SpecTableAttr.new('Symbol',    false, 'Symbol'.length + whitespace_padding),
        mode:        SpecTableAttr.new('Mode',      true,  'Mode'.length + whitespace_padding),
        type:        SpecTableAttr.new('Type',      true,  'Type'.length + whitespace_padding),
        sub_type:    SpecTableAttr.new('Sub-Type',  false, 'Sub-Type'.length + whitespace_padding),
        # spec SpecTableAttribute :description is called parameter in the spec table output to match historical docs
        description: SpecTableAttr.new('Parameter', false, 'Parameter'.length + whitespace_padding),
        min:         SpecTableAttr.new('Min',       false, 'Min'.length + whitespace_padding),
        typ:         SpecTableAttr.new('Typ',       false, 'Typ'.length + whitespace_padding),
        max:         SpecTableAttr.new('Max',       false, 'Max'.length + whitespace_padding),
        unit:        SpecTableAttr.new('Unit',      false, 'Unit'.length + whitespace_padding),
        audience:    SpecTableAttr.new('Audience',  false, 'Audience'.length + whitespace_padding)
        # notes:       SpecTableAttr.new('Notes',     false, 'Notes'.length + whitespace_padding)
      }
      # Calculate the padding needed in the spec table for the longest attr of all specs
      specs_to_be_shown.each do |spec|
        attrs_to_be_shown.each do |attr_name, attr_struct|
          unless spec.send(attr_name).nil?
            if spec.send(attr_name).class == Origen::Specs::Spec::Limit
              next if spec.send(attr_name).value.nil?
              current_padding = spec.send(attr_name).value.to_s.length + whitespace_padding
            else
              current_padding = spec.send(attr_name).to_s.length + whitespace_padding
            end
            attr_struct.padding = current_padding if attr_struct.padding < current_padding
            attr_struct.show = true # We found real data for this attr on at least one spec so show it in the spec table
          end
        end
      end
      # Now that each spec attribute padding construct the spec table header
      header = ''
      attrs_to_be_shown.each do |_attr_name, attr_struct|
        next if attr_struct.show == false
        header += "| #{attr_struct.table_text}".ljust(attr_struct.padding)
      end
      header += '|'
      ip_header = "| IP: #{specs_to_be_shown.first.ip_name} ".ljust(header.length - 1)
      ip_header += '|'
      table << '=' * header.length
      table << ip_header
      table << '=' * header.length
      table << header
      table << '-' * header.length
      # Create the data lines in the spec table
      specs_to_be_shown.each do |spec|
        data = ''
        attrs_to_be_shown.each do |attr_name, attr_struct|
          next if attr_struct.show == false
          if spec.send(attr_name).class == Origen::Specs::Spec::Limit
            data += "| #{spec.send(attr_name).value}".ljust(attr_struct.padding)
          else
            data += "| #{spec.send(attr_name)}".ljust(attr_struct.padding)
          end
        end
        table << data += '|'
      end
      table << '-' * header.length
      table.flatten.join("\n")
    end
Method to print a spec table to the console