Module: Origen::Specs::Checkers
- Included in:
- Origen::Specs, Spec, Spec
- Defined in:
- lib/origen/specs/checkers.rb
Instance Method Summary collapse
- #evaluate_limit(limit) ⇒ Object
- #get_mode ⇒ Object
-
#limits_ok? ⇒ Boolean
Check that min, max are not mixed with typ.
-
#name_audit(name) ⇒ Object
rubocop:disable Style/RescueModifier:.
Instance Method Details
#evaluate_limit(limit) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/origen/specs/checkers.rb', line 72 def evaluate_limit(limit) return limit if limit.is_a?(Numeric) return nil if limit.nil? if limit.is_a? Symbol limit = ':' + limit.to_s else limit.gsub!("\n", ' ') limit.scrub! end result = false if limit.match(/\:\S+/) limit_items = limit.split(/\:|\s+/).reject(&:empty?) references = limit.split(/\:|\s+/).select { |var| var.match(/^[a-zA-Z]\S+$/) } new_limit_items = [].tap do |limit_ary| limit_items.each do |item| if references.include? item # See if the limit is referencing a power domain, this should be extended to clocks # TODO: Expand limit references to check Origen::Clocks if Origen.top_level.respond_to? :power_domains if Origen.top_level.power_domains.include? item.to_sym limit_ary << Origen.top_level.power_domains(item.to_sym).nominal_voltage next end end if Origen.top_level.respond_to? :clocks if Origen.top_level.clocks.include? item.to_sym limit_ary << Origen.top_level.clocks(item.to_sym).freq_target next end end limit_ary << item else limit_ary << item end end end new_limit = new_limit_items.join(' ') new_limit_references = new_limit.split(/\:|\s+/).select { |var| var.match(/^[a-zA-Z]\S+$/) } if new_limit_references.empty? result = eval(new_limit).round(4) else return limit end elsif !!(limit.match(/^\d+\.\d+$/)) || !!(limit.match(/^-\d+\.\d+$/)) result = Float(limit).round(4) rescue false # Use the same four digits of accuracy as the Spec model elsif !!(limit.match(/\d+\.\d+\s+\d+\.\d+/)) # workaround for multiple specs authoring bug Origen.log.debug "Found two numbers without an operator in the limit string '#{limit}', choosing the first..." first_number = limit.match(/(\d+\.\d+)\s+\d+\.\d+/).captures.first result = Float(first_number).round(4) rescue false # Use the same four digits of accuracy as the Spec model # elsif !!(limit.match(/^tbd$/i)) # unique case of TBD or To Be Determined, will convert to symbol # limit = limit.downcase.to_sym else result = Integer(limit) rescue false end if result == false # Attempt to eval the limit because users could write a limit like "3.3 + 50.mV" # which would not work with the code above but should eval to a number 3.35 begin result = eval(limit) return result.round(4) if result.is_a? Numeric rescue ::SyntaxError, ::NameError, ::TypeError Origen.log.debug "Limit '#{limit}' had to be rescued, storing it as a #{limit.class}" if limit.is_a? Symbol return limit else return "#{limit}" end end else return result end end |
#get_mode ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/origen/specs/checkers.rb', line 58 def get_mode spec_mode = nil if current_mode.nil? if self == Origen.top_level spec_mode = :global else spec_mode = :local end else spec_mode = current_mode.name end spec_mode end |
#limits_ok? ⇒ Boolean
Check that min, max are not mixed with typ. If a user wants a baseline value for a spec use target as it will not be checked against pass/fail
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/origen/specs/checkers.rb', line 26 def limits_ok? status = true if (@min.exp.to_s.include? '/') || (@max.exp.to_s.include? '/') return status end if @min.exp.nil? ^ @max.exp.nil? @limit_type = :single_sided if @typ.exp # status = false Origen.log.debug "Spec #{@name} has a typical limit defined with either min or max. They are mutually exclusive, use 'target' when using min or max" end elsif @min.exp && @max.exp @limit_type = :double_sided # Both min and max must be numerical to compare them if @min.value.is_a?(Numeric) && @max.value.is_a?(Numeric) # Check that min and max make sense if @max.value <= @min.value || @min.value >= @max.value status = false Origen.log.debug "Spec #{@name} has min (#{@min.value}) and max (#{@max.value}) reversed" end # Check that target is OK unless @target.nil? if @target.value <= @min.value || @target.value >= @max.value status = false Origen.log.debug "Spec #{@name} has a target (#{@target.value}) that is not within the min (#{@min.value}) and max #{@max.value}) values" end end end end status end |
#name_audit(name) ⇒ Object
rubocop:disable Style/RescueModifier:
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/origen/specs/checkers.rb', line 5 def name_audit(name) return name if name.nil? return nil unless name.is_a?(Symbol) || name.is_a?(String) if name == :inspect Origen.log.debug ':inspect is a reserved spec name' return nil end if name.match(/^\d/) Origen.log.debug "Spec #{name} starts with a number" return nil end if name.match(/\s+/) Origen.log.debug "Spec #{name} contains white space, removing it" name.delete!(/\s+/) end name.is_a?(String) ? name.downcase.to_sym : name end |