class HDLRuby::Low::Select

Describes a section operation (generalization of the ternary operator).

NOTE: choice is using the value of select as an index.

Describes a section operation (generalization of the ternary operator).

NOTE: choice is using the value of select as an index.

Extends the Select class with generation of C text.

Extends the Select class with generation of hdr text.

Add the conversion to high.

Extends the Select class with generation of HDLRuby::High text.

Extends the Select class with functionality for converting booleans in assignments to select operators.

Extends the Select class with functionality for extracting expressions from cast.

Extends the Select class with fixing of types and constants.

Describes a section operation (generalization of the ternary operator).

NOTE: choice is using the value of select as an index.

Extends the Select class for checking if it a boolean epression or not.

Used for connection using choice. Enhance Select with generation of verilog code.

Attributes

select[R]

The selection child (connection).

Public Class Methods

new(type,operator,select,*choices) click to toggle source

Creates a new operator with type selecting from the value of select one of the choices. def initialize(operator,select,*choices)

Calls superclass method
# File lib/HDLRuby/hruby_low.rb, line 4892
def initialize(type,operator,select,*choices)
    # Initialize as a general operation.
    # super(operator)
    super(type,operator)
    # Check and set the selection.
    unless select.is_a?(Expression)
        raise AnyError,
              "Invalid class for an expression: #{select.class}"
    end
    @select = select
    # And set its parent.
    select.parent = self
    # Check and set the choices.
    @choices = []
    choices.each do |choice|
        self.add_choice(choice)
    end
end

Public Instance Methods

add_choice(choice) click to toggle source

Adds a choice.

# File lib/HDLRuby/hruby_low.rb, line 4960
def add_choice(choice)
    unless choice.is_a?(Expression)
        raise AnyError,
              "Invalid class for an expression: #{choice.class}"
    end
    # Set the parent of the choice.
    choice.parent = self
    # And add it.
    @choices << choice
    choice
end
boolean?() click to toggle source

Tells if the expression is boolean.

# File lib/HDLRuby/hruby_low_with_bool.rb, line 135
def boolean?
    # Boolean if all the choices are boolean.
    return !self.each_choice.any? {|c| !c.boolean? }
end
boolean_in_assign2select() click to toggle source

Converts booleans in assignments to select operators.

# File lib/HDLRuby/hruby_low_bool2select.rb, line 245
def boolean_in_assign2select
    # Recurse on the sub node.
    return Select.new(self.type,"?", 
                      self.select.boolean_in_assign2select,
                      *self.each_choice.map do |choice|
                          choice.boolean_in_assign2select
                      end )
    return self
end
casts_without_expression() click to toggle source

Extracts the expressions from the casts.

# File lib/HDLRuby/hruby_low_casts_without_expression.rb, line 253
def casts_without_expression
    # Recurse on the sub node.
    return Select.new(self.type,"?", 
                      self.select.casts_without_expression,
                      *self.each_choice.map do |choice|
                          choice.casts_without_expression
                      end )
    return self
end
clone() click to toggle source

Clones the select (deeply)

# File lib/HDLRuby/hruby_low.rb, line 5033
def clone
    return Select.new(@type, self.operator, @select.clone,
                      *@choices.map {|choice| choice.clone } )
end
delete_choice!(choice) click to toggle source

Deletes a choice.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1564
def delete_choice!(choice)
    if @choices.include?(choice) then
        # The choice is present, delete it.
        @choices.delete(choice)
        # And remove its parent.
        choice.parent = nil
    end
    choice
end
each_choice(&ruby_block) click to toggle source

Iterates over the choices.

Returns an enumerator if no ruby block is given.

# File lib/HDLRuby/hruby_low.rb, line 4975
def each_choice(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_choice) unless ruby_block
    # A ruby block? Apply it on each choice.
    @choices.each(&ruby_block)
end
each_deep(&ruby_block) click to toggle source

Iterates over each object deeply.

Returns an enumerator if no ruby block is given.

# File lib/HDLRuby/hruby_low.rb, line 4923
def each_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_deep) unless ruby_block
    # A ruby block? First apply it to current.
    ruby_block.call(self)
    # Then apply on the type.
    self.type.each_deep(&ruby_block)
    # Then apply on the select.
    self.select.each_deep(&ruby_block)
    # Then apply on the choices.
    self.each_choice do |choice|
        choice.each_deep(&ruby_block)
    end
end
each_expression(&ruby_block)
Alias for: each_node
each_node(&ruby_block) click to toggle source

Iterates over the expression children if any.

# File lib/HDLRuby/hruby_low.rb, line 4988
def each_node(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_node) unless ruby_block
    # A ruby block? Apply it on the children.
    ruby_block.call(@select)
    @choices.each(&ruby_block)
end
Also aliased as: each_expression
each_node_deep(&ruby_block) click to toggle source

Iterates over the nodes deeply if any.

# File lib/HDLRuby/hruby_low.rb, line 4999
def each_node_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_node_deep) unless ruby_block
    # A ruby block? First apply it to current.
    ruby_block.call(self)
    # And recurse on the children.
    @select.each_node_deep(&ruby_block)
    @choices.each { |choice| choice.each_node_deep(&ruby_block) }
end
each_ref_deep(&ruby_block) click to toggle source

Iterates over all the references encountered in the expression.

NOTE: do not iterate inside the references.

# File lib/HDLRuby/hruby_low.rb, line 5012
def each_ref_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_ref_deep) unless ruby_block
    # puts "each_ref_deep for Select"
    # A ruby block?
    # Recurse on the children.
    self.select.each_ref_deep(&ruby_block)
    self.each_choice do |choice|
        choice.each_ref_deep(&ruby_block)
    end
end
eql?(obj) click to toggle source

Comparison for hash: structural comparison.

Calls superclass method
# File lib/HDLRuby/hruby_low.rb, line 4939
def eql?(obj)
    # General comparison.
    return false unless super(obj)
    # Specific comparison.
    return false unless obj.is_a?(Select)
    return false unless @select.eql?(obj.select)
    idx = 0
    obj.each_choice do |choice|
        return false unless @choices[idx].eql?(choice)
        idx += 1
    end
    return false unless idx == @choices.size
    return true
end
explicit_types(type = nil) click to toggle source

Explicit the types conversions in the selection where type is the expected type of the condition if any.

# File lib/HDLRuby/hruby_low_fix_types.rb, line 293
def explicit_types(type = nil)
    # If there is no type to match, use the one of the selection.
    type = self.type unless type
    # Each choice child must match the type.
    return Select.new(type,self.operator,self.select.clone,
          *self.each_choice.map { |choice| choice.explicit_types(type)})
end
get_choice(index) click to toggle source

Gets a choice by index.

# File lib/HDLRuby/hruby_low.rb, line 4983
def get_choice(index)
    return @choices[index]
end
hash() click to toggle source

Hash function.

Calls superclass method
# File lib/HDLRuby/hruby_low.rb, line 4955
def hash
    return [super,@select,@choices].hash
end
immutable?() click to toggle source

Tells if the expression is immutable (cannot be written.)

# File lib/HDLRuby/hruby_low.rb, line 4912
def immutable?
    # Immutable if children are all immutable.
    return self.select.constant &&
      self.each_choice.reduce(true) do |r,c|
        r && c.immutable?
    end
end
map_choices!(&ruby_block) click to toggle source

Maps on the choices.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1555
def map_choices!(&ruby_block)
    @choices.map! do |choice|
        choice = ruby_block.call(choice)
        choice.parent = self unless choice.parent
        choice
    end
end
map_nodes!(&ruby_block) click to toggle source

Maps on the children.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1575
def map_nodes!(&ruby_block)
    @select = ruby_block.call(@select)
    @select.parent = self unless @select.parent
    map_choices!(&ruby_block)
end
replace_expressions!(node2rep) click to toggle source

Replaces sub expressions using node2rep table indicating the node to replace and the corresponding replacement. Returns the actually replaced nodes and their corresponding replacement.

NOTE: the replacement is duplicated.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1587
def replace_expressions!(node2rep)
    # First recurse on the children.
    res = {}
    self.each_node do |node|
        res.merge!(node.replace_expressions!(node2rep))
    end
    # Is there a replacement to do on the select?
    rep = node2rep[self.select]
    if rep then
        # Yes, do it.
        rep = rep.clone
        node = self.select
        # node.set_parent!(nil)
        self.set_select!(rep)
        # And register the replacement.
        res[node] = rep
    end
    # Is there a replacement of on a choice.
    self.map_choices! do |choice|
        rep = node2rep[choice]
        if rep then
            # Yes, do it.
            rep = rep.clone
            node = choice
            # node.set_parent!(nil)
            # And register the replacement.
            res[node] = rep
            rep
        else
            choice
        end
    end
    return res
end
set_select!(select) click to toggle source

Sets the select.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1543
def set_select!(select)
    # Check and set the selection.
    unless select.is_a?(Expression)
        raise AnyError,
              "Invalid class for an expression: #{select.class}"
    end
    @select = select
    # And set its parent.
    select.parent = self
end
to_c(level = 0) click to toggle source

Generates the C text of the equivalent HDLRuby code. level is the hierachical level of the object.

# File lib/HDLRuby/hruby_low2c.rb, line 1779
def to_c(level = 0)
    # Gather the possible selection choices.
    expressions = self.each_choice.to_a
    # Create the resulting string.
    # res = " " * (level*3)
    res = "({\n"
    # Overrides the upper sel, src0, src1, ..., and dst...
    # And allocates a new value for dst.
    res << (" " * ((level+1)*3))
    res << "Value sel;\n"
    res << (" " * ((level+1)*3))
    res << "Value #{expressions.size.times.map do |i| 
        "src#{i}"
    end.join(",")};\n"
    res << (" " * ((level+1)*3))
    res << "Value dst = get_value();\n"
    # Save the state of the value pool.
    res << (" " * ((level+1)*3))
    res << "unsigned int pool_state = get_value_pos();\n"
    # Compute the selection.
    res << (" " * ((level+1)*3))
    res << "sel = #{self.select.to_c(level+2)};\n"
    # Compute each choice expression.
    expressions.each_with_index do |expr,i|
        res << (" " * ((level+1)*3))
        res << "src#{i} = #{expr.to_c(level+2)};\n"
    end
    # Compute the resulting selection.
    res << (" " * ((level+1)*3))
    res << "select_value(sel,dst,#{expressions.size},"
    res << "#{expressions.size.times.map { |i| "src#{i}" }.join(",")}"
    res << ");\n"
    # Restore the state of the value pool.
    res << (" " * ((level+1)*3))
    res << "set_value_pos(pool_state);\n"
    # Close the computation.
    res << (" " * (level*3))
    res << "dst; })"
end
to_hdr(level = 0) click to toggle source

Generates the text of the equivalent hdr text. level is the hierachical level of the object.

# File lib/HDLRuby/hruby_low2hdr.rb, line 610
def to_hdr(level = 0)
    # The resulting string.
    res = ""
    # Generate the header.
    res << "mux(" + self.select.to_hdr(level) << ", "
    # Generate the choices
    res << self.each_choice.map do |choice|
        choice.to_hdr(level+1)
    end.join(", ")
    # Close the select.
    res << ")"
    # Return the resulting string.
    return res
end
to_high() click to toggle source

Creates a new high select expression.

# File lib/HDLRuby/hruby_low2high.rb, line 437
def to_high
    return HDLRuby::High::Select(self.type.to_high,self.operator,
                                 self.select.to_high,
                            self.each_choice.map { |ch| ch.to_high })
end
to_verilog() click to toggle source

Converts the system to Verilog code.

# File lib/HDLRuby/hruby_verilog.rb, line 1451
def to_verilog
    # Outputs the first and second choices (choice (0) and choice (1)).
    return "#{self.select.to_verilog} == 1 #{self.operator} #{self.get_choice(0).to_verilog} : #{self.get_choice(1).to_verilog}"
end
to_vhdl(level = 0, std_logic = false) click to toggle source

Generates the text of the equivalent HDLRuby::High code. level is the hierachical level of the object.

NOTE: assumes the existance of the mux function.

# File lib/HDLRuby/hruby_low2vhd.rb, line 1349
def to_vhdl(level = 0, std_logic = false)
    # The resulting string.
    res = ""
    # The number of arguments.
    num = @choices.size
    # Generate the header.
    res << "#{Low2VHDL.mux_name(self.type.to_vhdl(level),num)}(" +
            self.select.to_vhdl(level) << ", "
    # Generate the choices
    res << self.each_choice.map do |choice|
        choice.to_vhdl(level+1)
    end.join(", ")
    # Close the select.
    res << ")"
    # Return the resulting string.
    return res
end
use_name?(*names) click to toggle source

Tell if the expression includes a signal whose name is one of names.

# File lib/HDLRuby/hruby_low.rb, line 5025
def use_name?(*names)
    # Recurse on the select.
    return true if @select.use_name?(*names)
    # Recurse on the choices.
    return @choices.any? { |choice| choice.use_name?(*names) }
end