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_low2hdr.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_deep(&ruby_block) ⇒ Object
Iterates over each object deeply.
-
#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.
-
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.).
-
#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(res, level = 0) ⇒ Object
Generates the C text of the equivalent HDLRuby code.
-
#to_hdr(level = 0) ⇒ Object
Generates the text of the equivalent hdr text.
-
#to_high ⇒ Object
Creates a new high select expression.
-
#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, #to_c_expr
Methods included from Low2Symbol
Methods included from Hparent
#hierarchy, #no_parent!, #scope
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)
5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 |
# File 'lib/HDLRuby/hruby_low.rb', line 5167 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).
5162 5163 5164 |
# File 'lib/HDLRuby/hruby_low.rb', line 5162 def select @select end |
Instance Method Details
#add_choice(choice) ⇒ Object
Adds a +choice+.
5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 |
# File 'lib/HDLRuby/hruby_low.rb', line 5235 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.
257 258 259 260 261 262 263 264 265 |
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 257 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.
259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 259 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 ) self.set_select!(self.select.casts_without_expression!) self.map_choices! { |choice| choice.casts_without_expression! } return self end |
#clone ⇒ Object
Clones the select (deeply)
5308 5309 5310 5311 |
# File 'lib/HDLRuby/hruby_low.rb', line 5308 def clone return Select.new(@type, self.operator, @select.clone, *@choices.map {|choice| choice.clone } ) end |
#delete_choice!(choice) ⇒ Object
Deletes a choice.
1576 1577 1578 1579 1580 1581 1582 1583 1584 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1576 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.
5250 5251 5252 5253 5254 5255 |
# File 'lib/HDLRuby/hruby_low.rb', line 5250 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) ⇒ Object
Iterates over each object deeply.
Returns an enumerator if no ruby block is given.
5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 |
# File 'lib/HDLRuby/hruby_low.rb', line 5198 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_node(&ruby_block) ⇒ Object Also known as: each_expression
Iterates over the expression children if any.
5263 5264 5265 5266 5267 5268 5269 |
# File 'lib/HDLRuby/hruby_low.rb', line 5263 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.
5274 5275 5276 5277 5278 5279 5280 5281 5282 |
# File 'lib/HDLRuby/hruby_low.rb', line 5274 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.
5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 |
# File 'lib/HDLRuby/hruby_low.rb', line 5287 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.
5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 |
# File 'lib/HDLRuby/hruby_low.rb', line 5214 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.
312 313 314 315 316 317 318 |
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 312 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+.
5258 5259 5260 |
# File 'lib/HDLRuby/hruby_low.rb', line 5258 def get_choice(index) return @choices[index] end |
#hash ⇒ Object
Hash function.
5230 5231 5232 |
# File 'lib/HDLRuby/hruby_low.rb', line 5230 def hash return [super,@select,@choices].hash end |
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.)
5187 5188 5189 5190 5191 5192 5193 |
# File 'lib/HDLRuby/hruby_low.rb', line 5187 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) ⇒ Object
Maps on the choices.
1567 1568 1569 1570 1571 1572 1573 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1567 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.
1587 1588 1589 1590 1591 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1587 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.
1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1599 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.
1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1555 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(res, level = 0) ⇒ Object
Generates the C text of the equivalent HDLRuby code.
+level+ is the hierachical level of the object.
def to_c(level = 0)
def to_c(res,level = 0) # Gather the possible selection choices. expressions = self.each_choice.to_a # Create the resulting string. # res = "( 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 " res << expressions.size.times.map do |i| "src#{i" end.join(",") res << ";\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 = #HDLRuby::Low::Select.selfself.selectself.select.to_c(level+2);\n" res << "sel = " self.select.to_c(res,level+2) res << ";\n" # Compute each choice expression. expressions.each_with_index do |expr,i| res << (" " * ((level+1)*3)) # res << "src#i = #HDLRuby::Low::Select.exprexpr.to_c(level+2);\n" res << "src#i = " expr.to_c(res,level+2) res << ";\n" end # Compute the resulting selection. res << (" " * ((level+1)*3)) res << "select_value(sel,dst,#HDLRuby::Low::Select.expressionsexpressions.size," # res << "#{ |i| "src#{i" }.join(",")}" 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; })" return res end Generates the C text of the equivalent HDLRuby code. +level+ is the hierachical level of the object.
2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2619 def to_c(res,level = 0) # Save the value pool state. res << (" " * (level*3)) << "PV;\n" # Gather the possible selection choices. expressions = self.each_choice.to_a # Create the resulting string. # Compute the selection. self.select.to_c(res,level) # Compute each choice expression. expressions.each_with_index do |expr,i| expr.to_c(res,level) end # Compute the resulting selection. res << (" " * (level*3)) res << "hselect(#{expressions.size});\n" # Restore the value pool state. res << (" " * (level*3)) << "RV;\n" return res end |
#to_hdr(level = 0) ⇒ Object
Generates the text of the equivalent hdr text. +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_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 ⇒ Object
Creates a new high select expression.
437 438 439 440 441 |
# 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 ⇒ Object
Converts the system to Verilog code.
1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1525 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}" res = "" sels = self.select.to_verilog @choices[0..-2].each_with_index do |choice,i| res << "#{sels} == #{i} ? #{choice.to_verilog} : " end res << @choices[-1].to_verilog return res 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.
1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1361 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+.
5300 5301 5302 5303 5304 5305 |
# File 'lib/HDLRuby/hruby_low.rb', line 5300 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 |