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
The selection child (connection).
Public Class Methods
Creates a new operator with type
selecting from the value of select
one of the choices
. def initialize(operator,select,*choices)
# 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
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
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
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
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
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
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
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
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
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
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
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
Comparison for hash: structural comparison.
# 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 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
Gets a choice by index
.
# File lib/HDLRuby/hruby_low.rb, line 4983 def get_choice(index) return @choices[index] end
Hash
function.
# File lib/HDLRuby/hruby_low.rb, line 4955 def hash return [super,@select,@choices].hash end
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
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
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
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
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
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
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
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
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
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
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