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,
lib/HDLRuby/hruby_low_casts_without_expression.rb
Overview
Extends the Select class with functionality for extracting expressions from cast.
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.
-
#casts_without_expression ⇒ Object
Extracts the expressions from the casts.
-
#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.
-
#use_name?(*names) ⇒ Boolean
Tell if the expression includes a signal whose name is one of +names+.
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)
4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 |
# File 'lib/HDLRuby/hruby_low.rb', line 4277 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).
4272 4273 4274 |
# File 'lib/HDLRuby/hruby_low.rb', line 4272 def select @select end |
Instance Method Details
#add_choice(choice) ⇒ Object
Adds a +choice+.
4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 |
# File 'lib/HDLRuby/hruby_low.rb', line 4318 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 |
#casts_without_expression ⇒ Object
Extracts the expressions from the casts.
239 240 241 242 243 244 245 246 247 |
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 239 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 ⇒ Object
Clones the select (deeply)
4391 4392 4393 4394 |
# File 'lib/HDLRuby/hruby_low.rb', line 4391 def clone return Select.new(@type, self.operator, @select.clone, *@choices.map {|choice| choice.clone } ) end |
#delete_choice!(choice) ⇒ Object
Deletes a choice.
1494 1495 1496 1497 1498 1499 1500 1501 1502 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1494 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.
4333 4334 4335 4336 4337 4338 |
# File 'lib/HDLRuby/hruby_low.rb', line 4333 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.
4346 4347 4348 4349 4350 4351 4352 |
# File 'lib/HDLRuby/hruby_low.rb', line 4346 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.
4357 4358 4359 4360 4361 4362 4363 4364 4365 |
# File 'lib/HDLRuby/hruby_low.rb', line 4357 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.
4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 |
# File 'lib/HDLRuby/hruby_low.rb', line 4370 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.
4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 |
# File 'lib/HDLRuby/hruby_low.rb', line 4297 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+.
4341 4342 4343 |
# File 'lib/HDLRuby/hruby_low.rb', line 4341 def get_choice(index) return @choices[index] end |
#hash ⇒ Object
Hash function.
4313 4314 4315 |
# File 'lib/HDLRuby/hruby_low.rb', line 4313 def hash return [super,@select,@choices].hash end |
#map_choices!(&ruby_block) ⇒ Object
Maps on the choices.
1485 1486 1487 1488 1489 1490 1491 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1485 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.
1505 1506 1507 1508 1509 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1505 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.
1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1517 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.
1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1473 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.
1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 1736 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.
1464 1465 1466 1467 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1464 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.
1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1325 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) ⇒ Boolean
Tell if the expression includes a signal whose name is one of +names+.
4383 4384 4385 4386 4387 4388 |
# File 'lib/HDLRuby/hruby_low.rb', line 4383 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 |