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_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!, #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.
273 274 275 276 277 278 |
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 273 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)
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.
1705 1706 1707 1708 1709 1710 1711 1712 1713 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1705 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.
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 326 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.
1694 1695 1696 1697 1698 1699 1700 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1694 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.
2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2720 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.
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
1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1807 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)
1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1388 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 |