module Origen module PowerDomains class PowerDomain attr_accessor :id, :description, :voltage_range, :nominal_voltage, :setpoint # Generic Power Domain Name # This is the power supply that can be blocked off to multiple power supplies # For example, Power Domain for DDR blocks could be GVDD, then the actual # power supplies can be different for each DDR block. # DDR1 --> G1VDD # DDR2 --> G2VDD attr_accessor :generic_name # Actual Power Domain Name attr_accessor :actual_name # Allowed Voltage Points # Some power supplies can be at different levels, e.g. 1.8V or 3.3V # Could be a signal voltage or an array of voltages attr_accessor :voltages # Display Names # Hash of display names # display_name = { # input: Input voltage name, e.g. VIN # output: Output voltage name, e.g. VOUT # default: Regular Voltage name, e.g. VDD attr_accessor :display_name def initialize(id, options = {}, &block) @id = id @description = '' @display_name = {} @id = @id.symbolize unless @id.is_a? Symbol options.each { |k, v| instance_variable_set("@#{k}", v) } (block.arity < 1 ? (instance_eval(&block)) : block.call(self)) if block_given? fail unless attrs_ok? end def name @id end # Sets setpoint equal to nominal_voltage def setpoint_to_nominal @setpoint = @nominal_voltage end # Returns an Array of all pins that reference the power domain def pins signal_pins + ground_pins + power_pins end # Returns an Array of signal pin IDs that match the power domain ID def signal_pins Origen.top_level.pins.select { |_pin_id, p| p.supply == id }.keys end # Returns an Array of ground pin IDs that match the power domain ID def ground_pins Origen.top_level.ground_pins.select { |_pin_id, p| p.supply == id }.keys end # Returns an Array of ground pin IDs that match the power domain ID def power_pins Origen.top_level.power_pins.select { |_pin_id, p| p.supply == id }.keys end # Checks for the existence of a signal pin that references the power domain def has_signal_pin?(pin) signal_pins.include?(pin) ? true : false end # Checks for the existence of a signal pin that references the power domain def has_ground_pin?(pin) ground_pins.include?(pin) ? true : false end # Checks for the existence of a signal pin that references the power domain def has_power_pin?(pin) power_pins.include?(pin) ? true : false end # Checks if a pin references the power domain, regardless of type def has_pin?(pin) pins.include? pin end # Checks for a pin type, returns nil if it is not found def pin_type(pin) if self.has_pin?(pin) == false nil else [:signal, :ground, :power].each do |pintype| return pintype if send("has_#{pintype}_pin?", pin) end end end # Nominal voltage def nominal_voltage @nominal_voltage end alias_method :nominal, :nominal_voltage alias_method :nom, :nominal_voltage # Current setpoint, defaults top nil on init def setpoint @setpoint end alias_method :curr_value, :setpoint alias_method :value, :setpoint # Acceptable voltage range def voltage_range @voltage_range end alias_method :range, :voltage_range # Setter for setpoint def setpoint=(val) unless setpoint_ok?(val) Origen.log.warn("Setpoint (#{setpoint_string(val)}) for power domain '#{name}' is not within the voltage range (#{voltage_range_string})!") end @setpoint = val end # Checks if the setpoint is valid def setpoint_ok?(val = nil) if val.nil? voltage_range.include?(setpoint) ? true : false else voltage_range.include?(val) ? true : false end end alias_method :value_ok?, :setpoint_ok? alias_method :val_ok?, :setpoint_ok? def display_names(default_name) @display_name[:default] = default_name @display_name[:input] = change_subscript('IN') @display_name[:output] = change_subscript('OUT') end def method_missing(m, *args, &block) ivar = "@#{m.to_s.gsub('=', '')}" ivar_sym = ":#{ivar}" if m.to_s =~ /=$/ define_singleton_method(m) do |val| instance_variable_set(ivar, val) end elsif instance_variables.include? ivar_sym instance_variable_get(ivar) else define_singleton_method(m) do instance_variable_get(ivar) end end send(m, *args, &block) end private def attrs_ok? return_value = true unless description.is_a? String Origen.log.error("Power domain attribute 'description' must be a String!") return_value = false end return_value = false unless voltages_ok? return_value end def setpoint_string(val = nil) if val.nil? setpoint.as_units('V') else val.as_units('V') end end def voltages_ok? if nominal_voltage.nil? false elsif voltage_range.nil? Origen.log.error("PPEKit: Missing voltage range for power domain '#{name}'!") false elsif voltage_range.is_a? Range if voltage_range.include?(nominal_voltage) true else Origen.log.error("PPEKit: Nominal voltage #{nominal_voltage} is not inbetween the voltage range #{voltage_range} for power domain '#{name}'!") false end else Origen.log.error("Power domain attribute 'voltage_range' must be a Range!") return_value = false end end def change_subscript(new_subscript) tmp = @display_name[:default].dup sub_input = tmp.at_css 'sub' sub_input.content = new_subscript unless sub_input.nil? tmp end end end end