Class: HDLRuby::Low::Concat
- Inherits:
-
Expression
- Object
- Base::Expression
- Expression
- HDLRuby::Low::Concat
- Includes:
- MutableConcat
- 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_bool2select.rb,
lib/HDLRuby/hruby_low_casts_without_expression.rb
Overview
Extends the Concat 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
Attributes inherited from Expression
Attributes included from Hparent
Instance Method Summary collapse
-
#add_expression(expression) ⇒ Object
Adds an +expression+ to concat.
-
#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 concatenated expression (deeply).
-
#delete_expression!(expression) ⇒ Object
Delete an expression.
-
#each_deep(&ruby_block) ⇒ Object
Iterates over each object deeply.
-
#each_expression(&ruby_block) ⇒ Object
(also: #each_node)
Iterates over the concatenated expressions.
-
#each_node_deep(&ruby_block) ⇒ Object
Iterates over the nodes deeply if any.
-
#eql?(obj) ⇒ Boolean
Comparison for hash: structural comparison.
-
#explicit_types(type = nil) ⇒ Object
Explicit the types conversions in the concat where +type+ is the expected type of the condition if any.
-
#hash ⇒ Object
Hash function.
-
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.).
-
#initialize(type, expressions = []) ⇒ Concat
constructor
Creates a new concatenation with +type+ of several +expressions+ together.
-
#map_expressions!(&ruby_block) ⇒ Object
(also: #map_nodes!)
Maps on the expression.
-
#to_c(res, level = 0) ⇒ Object
Generates the C text for the equivalent HDLRuby code.
-
#to_c_expr(res, level = 0) ⇒ Object
Generates the C text of expression for the equivalent HDLRuby code.
-
#to_hdr(level = 0) ⇒ Object
Generates the text of the equivalent hdr text.
-
#to_high ⇒ Object
Creates a new high concat expression.
- #to_verilog ⇒ Object
-
#to_vhdl(level = 0, type = self.type) ⇒ 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 included from MutableConcat
Methods inherited from Expression
#boolean?, #break_types!, #each_ref_deep, #extract_selects_to!, #leftvalue?, #replace_expressions!, #replace_names!, #rightvalue?, #set_type!, #statement
Methods included from Low2Symbol
Methods included from Hparent
Constructor Details
#initialize(type, expressions = []) ⇒ Concat
Creates a new concatenation with +type+ of several +expressions+
together.
def initialize(expressions = [])
5057 5058 5059 5060 5061 5062 5063 |
# File 'lib/HDLRuby/hruby_low.rb', line 5057 def initialize(type,expressions = []) super(type) # Initialize the array of expressions that are concatenated. @expressions = [] # Check and add the expressions. expressions.each { |expression| self.add_expression(expression) } end |
Instance Method Details
#add_expression(expression) ⇒ Object
Adds an +expression+ to concat.
5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 |
# File 'lib/HDLRuby/hruby_low.rb', line 5110 def add_expression(expression) # Check expression. unless expression.is_a?(Expression) then raise AnyError, "Invalid class for an expression: #{expression.class}" end # Add it. @expressions << expression # And set its parent. expression.parent = self expression end |
#boolean_in_assign2select ⇒ Object
Converts booleans in assignments to select operators.
261 262 263 264 265 266 |
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 261 def boolean_in_assign2select # Recurse on the sub expressions. return Concat.new(self.type,self.each_expression.map do |expr| expr.boolean_in_assign2select end ) end |
#casts_without_expression! ⇒ Object
Extracts the expressions from the casts.
277 278 279 280 281 282 283 284 |
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 277 def casts_without_expression! # Recurse on the sub expressions. # return Concat.new(self.type,self.each_expression.map do |expr| # expr.casts_without_expression # end ) self.map_expressions! {|expr| expr.casts_without_expression! } return self end |
#clone ⇒ Object
Clones the concatenated expression (deeply)
5153 5154 5155 5156 |
# File 'lib/HDLRuby/hruby_low.rb', line 5153 def clone return Concat.new(@type, @expressions.map {|expr| expr.clone } ) end |
#delete_expression!(expression) ⇒ Object
Delete an expression.
1688 1689 1690 1691 1692 1693 1694 1695 1696 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1688 def delete_expression!(expression) if @expressions.include?(expression) then # The expression is present, delete it. @expressions.delete(expression) # And remove its parent. expression.parent = nil end expression end |
#each_deep(&ruby_block) ⇒ Object
Iterates over each object deeply.
Returns an enumerator if no ruby block is given.
5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 |
# File 'lib/HDLRuby/hruby_low.rb', line 5076 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 expressions. self.each_expression do |expr| expr.each_deep(&ruby_block) end end |
#each_expression(&ruby_block) ⇒ Object Also known as: each_node
Iterates over the concatenated expressions.
Returns an enumerator if no ruby block is given.
5126 5127 5128 5129 5130 5131 |
# File 'lib/HDLRuby/hruby_low.rb', line 5126 def each_expression(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_expression) unless ruby_block # A ruby block? Apply it on each children. @expressions.each(&ruby_block) end |
#each_node_deep(&ruby_block) ⇒ Object
Iterates over the nodes deeply if any.
5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 |
# File 'lib/HDLRuby/hruby_low.rb', line 5135 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. self.each_expression do |expr| expr.each_node_deep(&ruby_block) end end |
#eql?(obj) ⇒ Boolean
Comparison for hash: structural comparison.
5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 |
# File 'lib/HDLRuby/hruby_low.rb', line 5090 def eql?(obj) # General comparison. return false unless super(obj) # Specific comparison. return false unless obj.is_a?(Concat) idx = 0 obj.each_expression do |expression| return false unless @expressions[idx].eql?(expression) idx += 1 end return false unless idx == @expressions.size return true end |
#explicit_types(type = nil) ⇒ Object
Explicit the types conversions in the concat where +type+ is the expected type of the condition if any.
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 307 def explicit_types(type = nil) # Is there a type to match? if type then # Yes, update the concat to the type. # Get the real type in case of typedef. type = type.def while type.is_a?(TypeDef) # Is it an array type? if type.is_a?(TypeVector) then # Yes, update the concat without subcasting. return Concat.new(type,self.each_expression.map do |expr| expr.explicit_types end) else # No, it should be a tuple. return Concat.new(type, self.each_expression.map.with_index do |expr,i| expr.explicit_types(type.get_type(i)) end) end else # No, recurse on the sub expressions. return Concat.new(self.type, self.each_expression.map do |expr| expr.explicit_types end) end end |
#hash ⇒ Object
Hash function.
5105 5106 5107 |
# File 'lib/HDLRuby/hruby_low.rb', line 5105 def hash return [super,@expressions].hash end |
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.)
5066 5067 5068 5069 5070 5071 |
# File 'lib/HDLRuby/hruby_low.rb', line 5066 def immutable? # Immutable if children are all immutable. return self.each_expression.reduce(true) do |r,c| r && c.immutable? end end |
#map_expressions!(&ruby_block) ⇒ Object Also known as: map_nodes!
Maps on the expression.
1677 1678 1679 1680 1681 1682 1683 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1677 def map_expressions!(&ruby_block) @expressions.map! do |expression| expression = ruby_block.call(expression) expression.parent = self unless expression.parent expression end end |
#to_c(res, level = 0) ⇒ Object
Generates the C text for the equivalent HDLRuby code.
+level+ is the hierachical level of the object.
def to_c(res,level = 0) # Gather the content to concat. expressions = self.each_expression.to_a # Create the resulting string. res << "( # Overrides the upper src0, src1, ..., and dst... # And allocates a new value for dst. 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 each sub expression. expressions.each_with_index do |expr,i| res << (" " * ((level+1)*3)) res << "src#i = " expr.to_c_expr(res,level+2) res << ";\n" end # Compute the direction. # Compute the resulting concatenation. res << (" " * ((level+1)*3)) res << "concat_value(#HDLRuby::Low::Concat.expressionsexpressions.size," res << "#== :little ? 1 : 0,dst," 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 for the equivalent HDLRuby code. +level+ is the hierachical level of the object.
2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2439 def to_c(res,level = 0) # Save the value pool state. res << (" " * (level*3)) << "PV;\n" # Gather the content to concat. expressions = self.each_expression.to_a # Compute each sub expression. expressions.each_with_index do |expr,i| expr.to_c(res,level+2) end # Compute the resulting concatenation. res << (" " * ((level+1)*3)) res << "sconcat(#{expressions.size}," res << (self.type.direction == :little ? "1" : "0") res << ");\n" # Restore the value pool state. res << (" " * (level*3)) << "RV;\n" return res end |
#to_c_expr(res, level = 0) ⇒ Object
Generates the C text of expression for the equivalent HDLRuby code. +level+ is the hierachical level of the object.
2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2460 def to_c_expr(res,level = 0) # Gather the content to concat. expressions = self.each_expression.to_a # Create the resulting string. res << "({\n" # Overrides the upper src0, src1, ..., and dst... # And allocates a new value for dst. 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 value pool state. res << (" " * (level*3)) << "SV;\n" # Compute each sub expression. expressions.each_with_index do |expr,i| res << (" " * ((level+1)*3)) res << "src#{i} = " expr.to_c_expr(res,level+2) res << ";\n" end # Compute the direction. # Compute the resulting concatenation. res << (" " * ((level+1)*3)) res << "concat_value(#{expressions.size}," res << "#{self.type.direction == :little ? 1 : 0},dst," res << expressions.size.times.map { |i| "src#{i}" }.join(",") res << ");\n" # Save the value pool state. res << (" " * (level*3)) << "SV;\n" # Close the computation. res << (" " * (level*3)) res << "dst; })" return res end |
#to_hdr(level = 0) ⇒ Object
Generates the text of the equivalent hdr text. +level+ is the hierachical level of the object.
631 632 633 634 635 636 637 638 639 640 641 642 643 644 |
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 631 def to_hdr(level = 0) # The resulting string. res = "" # Generate the header. res << "[ " # Generate the expressions. res << self.each_expression.map do |expression| expression.to_hdr(level+1) end.join(", ") # Close the select. res << " ]" # Return the resulting string. return res end |
#to_high ⇒ Object
Creates a new high concat expression.
448 449 450 451 |
# File 'lib/HDLRuby/hruby_low2high.rb', line 448 def to_high return HDLRuby::High::Concat.new(self.type.to_high, self.each_expression.map { |ex| ex.to_high }) end |
#to_verilog ⇒ Object
1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1765 def to_verilog expression = self.each_expression.to_a result = "{" expression[0..-2].each do |expression| result << "#{expression.to_verilog}," end result << "#{expression.last.to_verilog}}" return result end |
#to_vhdl(level = 0, type = self.type) ⇒ Object
Generates the text of the equivalent HDLRuby::High code. +type+ is the expected type of the content. +level+ is the hierachical level of the object. def to_vhdl(type,level = 0)
1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1375 def to_vhdl(level = 0, type = self.type) raise "Invalid class for a type: #{type.class}" unless type.is_a?(Type) # The resulting string. res = "" # Generate the header. # Generate the expressions. # Depends if it is an initialization or not. # if self.type.is_a?(TypeTuple) then if self.parent.is_a?(SignalC) then res << "( " << self.each_expression.map do |expression| Low2VHDL.to_type(type,expression) end.join(",\n#{" "*((level+1)*3)}") << " )" else # Compute the width of the concatenation. width = self.each_expression.reduce(0) do |sum,expr| sum += expr.type.width end # Generate the missing bits if any. width = type.width - width res << '"' + "0" * width + '" & ' if width > 0 # Generate the concatenation. res << self.each_expression.map do |expression| # "(" + Low2VHDL.to_type(type,expression) + ")" "(" + expression.to_vhdl(level+1) + ")" end.join(" & ") end # Return the resulting string. return res end |
#use_name?(*names) ⇒ Boolean
Tell if the expression includes a signal whose name is one of +names+.
5147 5148 5149 5150 |
# File 'lib/HDLRuby/hruby_low.rb', line 5147 def use_name?(*names) # Recurse on the expressions. return @expressions.any? { |expr| expr.use_name?(*names) } end |