Class: HDLRuby::Low::Select
- Inherits:
-
Operation
- Object
- Base::Expression
- Expression
- Operation
- HDLRuby::Low::Select
- Defined in:
- lib/HDLRuby/hruby_db.rb,
lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_low2c.rb,
lib/HDLRuby/hruby_low2vhd.rb,
lib/HDLRuby/hruby_verilog.rb,
lib/HDLRuby/hruby_low2high.rb,
lib/HDLRuby/hruby_low_mutable.rb,
lib/HDLRuby/hruby_low_skeleton.rb,
lib/HDLRuby/hruby_low_fix_types.rb,
lib/HDLRuby/hruby_low_with_bool.rb,
lib/HDLRuby/hruby_low_bool2select.rb
Overview
Extends the Select class with functionality for converting booleans in assignments to select operators.
Direct Known Subclasses
Constant Summary
Constants included from Low2Symbol
Low2Symbol::Low2SymbolPrefix, Low2Symbol::Low2SymbolTable, Low2Symbol::Symbol2LowTable
Instance Attribute Summary collapse
-
#select ⇒ Object
readonly
The selection child (connection).
Attributes inherited from Operation
Attributes inherited from Expression
Attributes included from Hparent
Instance Method Summary collapse
-
#add_choice(choice) ⇒ Object
Adds a +choice+.
-
#boolean? ⇒ Boolean
Tells if the expression is boolean.
-
#boolean_in_assign2select ⇒ Object
Converts booleans in assignments to select operators.
-
#clone ⇒ Object
Clones the select (deeply).
-
#delete_choice!(choice) ⇒ Object
Deletes a choice.
-
#each_choice(&ruby_block) ⇒ Object
Iterates over the choices.
-
#each_node(&ruby_block) ⇒ Object
(also: #each_expression)
Iterates over the expression children if any.
-
#each_node_deep(&ruby_block) ⇒ Object
Iterates over the nodes deeply if any.
-
#each_ref_deep(&ruby_block) ⇒ Object
Iterates over all the references encountered in the expression.
-
#eql?(obj) ⇒ Boolean
Comparison for hash: structural comparison.
-
#explicit_types(type = nil) ⇒ Object
Explicit the types conversions in the selection where +type+ is the expected type of the condition if any.
-
#get_choice(index) ⇒ Object
Gets a choice by +index+.
-
#hash ⇒ Object
Hash function.
-
#initialize(type, operator, select, *choices) ⇒ Select
constructor
Creates a new operator with +type+ selecting from the value of +select+ one of the +choices+.
-
#map_choices!(&ruby_block) ⇒ Object
Maps on the choices.
-
#map_nodes!(&ruby_block) ⇒ Object
Maps on the children.
-
#replace_expressions!(node2rep) ⇒ Object
Replaces sub expressions using +node2rep+ table indicating the node to replace and the corresponding replacement.
-
#set_select!(select) ⇒ Object
Sets the select.
-
#to_c(level = 0) ⇒ Object
Generates the C text of the equivalent HDLRuby::High code.
-
#to_high(level = 0) ⇒ Object
Generates the text of the equivalent HDLRuby::High code.
-
#to_verilog ⇒ Object
Converts the system to Verilog code.
-
#to_vhdl(level = 0, std_logic = false) ⇒ Object
Generates the text of the equivalent HDLRuby::High code.
Methods inherited from Operation
Methods inherited from Expression
#break_types!, #extract_selects_to!, #leftvalue?, #replace_names!, #rightvalue?, #set_type!, #statement
Methods included from Low2Symbol
Methods included from Hparent
Constructor Details
#initialize(type, operator, select, *choices) ⇒ Select
Creates a new operator with +type+ selecting from the value of +select+ one of the +choices+. def initialize(operator,select,*choices)
4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 |
# File 'lib/HDLRuby/hruby_low.rb', line 4175 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 |
Instance Attribute Details
#select ⇒ Object (readonly)
The selection child (connection).
4170 4171 4172 |
# File 'lib/HDLRuby/hruby_low.rb', line 4170 def select @select end |
Instance Method Details
#add_choice(choice) ⇒ Object
Adds a +choice+.
4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 |
# File 'lib/HDLRuby/hruby_low.rb', line 4216 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? ⇒ Boolean
Tells if the expression is boolean.
135 136 137 138 |
# 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 ⇒ Object
Converts booleans in assignments to select operators.
231 232 233 234 235 236 237 238 239 |
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 231 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 |
#clone ⇒ Object
Clones the select (deeply)
4281 4282 4283 4284 |
# File 'lib/HDLRuby/hruby_low.rb', line 4281 def clone return Select.new(@type, self.operator, @select.clone, *@choices.map {|choice| choice.clone } ) end |
#delete_choice!(choice) ⇒ Object
Deletes a choice.
1406 1407 1408 1409 1410 1411 1412 1413 1414 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1406 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) ⇒ Object
Iterates over the choices.
Returns an enumerator if no ruby block is given.
4231 4232 4233 4234 4235 4236 |
# File 'lib/HDLRuby/hruby_low.rb', line 4231 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_node(&ruby_block) ⇒ Object Also known as: each_expression
Iterates over the expression children if any.
4244 4245 4246 4247 4248 4249 4250 |
# File 'lib/HDLRuby/hruby_low.rb', line 4244 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 |
#each_node_deep(&ruby_block) ⇒ Object
Iterates over the nodes deeply if any.
4255 4256 4257 4258 4259 4260 4261 4262 4263 |
# File 'lib/HDLRuby/hruby_low.rb', line 4255 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) ⇒ Object
Iterates over all the references encountered in the expression.
NOTE: do not iterate inside the references.
4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 |
# File 'lib/HDLRuby/hruby_low.rb', line 4268 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) ⇒ Boolean
Comparison for hash: structural comparison.
4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 |
# File 'lib/HDLRuby/hruby_low.rb', line 4195 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) ⇒ Object
Explicit the types conversions in the selection where +type+ is the expected type of the condition if any.
279 280 281 282 283 284 285 |
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 279 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) ⇒ Object
Gets a choice by +index+.
4239 4240 4241 |
# File 'lib/HDLRuby/hruby_low.rb', line 4239 def get_choice(index) return @choices[index] end |
#hash ⇒ Object
Hash function.
4211 4212 4213 |
# File 'lib/HDLRuby/hruby_low.rb', line 4211 def hash return [super,@select,@choices].hash end |
#map_choices!(&ruby_block) ⇒ Object
Maps on the choices.
1397 1398 1399 1400 1401 1402 1403 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1397 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) ⇒ Object
Maps on the children.
1417 1418 1419 1420 1421 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1417 def map_nodes!(&ruby_block) @select = ruby_block.call(@select) @select.parent = self unless @select.parent map_choices!(&ruby_block) end |
#replace_expressions!(node2rep) ⇒ Object
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.
1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1429 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) ⇒ Object
Sets the select.
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1385 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) ⇒ Object
Generates the C text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.
1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 1713 def to_c(level = 0) # res = "select_value(#{self.select.to_c(level)}," + # "#{self.each_choice.to_a.size}" # self.each_choice { |choice| res << ",#{choice.to_c(level)}" } # res << ")" # return res # 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_high(level = 0) ⇒ Object
Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.
610 611 612 613 614 615 616 617 618 619 620 621 622 623 |
# File 'lib/HDLRuby/hruby_low2high.rb', line 610 def to_high(level = 0) # The resulting string. res = "" # Generate the header. res << "mux(" + self.select.to_high(level) << ", " # Generate the choices res << self.each_choice.map do |choice| choice.to_high(level+1) end.join(", ") # Close the select. res << ")" # Return the resulting string. return res end |
#to_verilog ⇒ Object
Converts the system to Verilog code.
1395 1396 1397 1398 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1395 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) ⇒ Object
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.
1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1310 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 |