Class: HDLRuby::Low::Concat
- Inherits:
-
Expression
- Object
- Expression
- HDLRuby::Low::Concat
- Includes:
- MutableConcat
- Defined in:
- 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
Describes a concatenation expression.
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_hdr(level = 0) ⇒ Object
Generates the text of the equivalent hdr text.
-
#to_high ⇒ Object
Creates a new high concat expression.
-
#to_verilog ⇒ Object
Enhances Concat with generation of verilog code.
-
#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!, #signal2subs!, #statement, #to_c_expr
Methods included from Low2Symbol
Methods included from Hparent
#hierarchy, #no_parent!, #scope
Constructor Details
#initialize(type, expressions = []) ⇒ Concat
Creates a new concatenation with +type+ of several +expressions+
together.
def initialize(expressions = [])
5492 5493 5494 5495 5496 5497 5498 5499 |
# File 'lib/HDLRuby/hruby_low.rb', line 5492 def initialize(type,expressions = []) super(type) # puts "Building concat=#{self} with direction=#{type.direction}\n" # 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.
5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 |
# File 'lib/HDLRuby/hruby_low.rb', line 5546 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.
282 283 284 285 286 287 |
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 282 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.
284 285 286 287 288 289 290 291 |
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 284 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)
5589 5590 5591 5592 |
# File 'lib/HDLRuby/hruby_low.rb', line 5589 def clone return Concat.new(@type, @expressions.map {|expr| expr.clone } ) end |
#delete_expression!(expression) ⇒ Object
Delete an expression.
1650 1651 1652 1653 1654 1655 1656 1657 1658 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1650 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.
5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 |
# File 'lib/HDLRuby/hruby_low.rb', line 5512 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.
5562 5563 5564 5565 5566 5567 |
# File 'lib/HDLRuby/hruby_low.rb', line 5562 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.
5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 |
# File 'lib/HDLRuby/hruby_low.rb', line 5571 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.
5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 |
# File 'lib/HDLRuby/hruby_low.rb', line 5526 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.
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 |
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 351 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.
5541 5542 5543 |
# File 'lib/HDLRuby/hruby_low.rb', line 5541 def hash return [super,@expressions].hash end |
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.)
5502 5503 5504 5505 5506 5507 |
# File 'lib/HDLRuby/hruby_low.rb', line 5502 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.
1639 1640 1641 1642 1643 1644 1645 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1639 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.
2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2734 def to_c(res,level = 0) # puts "to_c fo concat=#{self} with type=#{self.type} and direction=#{self.type.direction}" # 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)) # puts "self.type=#{self.type} self.type.direction=#{self.type.direction}\n" 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_hdr(level = 0) ⇒ Object
Generates the text of the equivalent hdr text. +level+ is the hierachical level of the object.
651 652 653 654 655 656 657 658 659 660 661 662 663 664 |
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 651 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.
484 485 486 487 |
# File 'lib/HDLRuby/hruby_low2high.rb', line 484 def to_high return HDLRuby::High::Concat.new(self.type.to_high, self.each_expression.map { |ex| ex.to_high }) end |
#to_verilog ⇒ Object
Enhances Concat with generation of verilog code.
1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1840 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)
1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1417 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+.
5583 5584 5585 5586 |
# File 'lib/HDLRuby/hruby_low.rb', line 5583 def use_name?(*names) # Recurse on the expressions. return @expressions.any? { |expr| expr.use_name?(*names) } end |