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!, #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 = [])
5321 5322 5323 5324 5325 5326 5327 5328 |
# File 'lib/HDLRuby/hruby_low.rb', line 5321 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.
5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 |
# File 'lib/HDLRuby/hruby_low.rb', line 5375 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)
5418 5419 5420 5421 |
# File 'lib/HDLRuby/hruby_low.rb', line 5418 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.
5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 |
# File 'lib/HDLRuby/hruby_low.rb', line 5341 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.
5391 5392 5393 5394 5395 5396 |
# File 'lib/HDLRuby/hruby_low.rb', line 5391 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.
5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 |
# File 'lib/HDLRuby/hruby_low.rb', line 5400 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.
5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 |
# File 'lib/HDLRuby/hruby_low.rb', line 5355 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.
5370 5371 5372 |
# File 'lib/HDLRuby/hruby_low.rb', line 5370 def hash return [super,@expressions].hash end |
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.)
5331 5332 5333 5334 5335 5336 |
# File 'lib/HDLRuby/hruby_low.rb', line 5331 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.
2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2688 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.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)
1387 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 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1387 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+.
5412 5413 5414 5415 |
# File 'lib/HDLRuby/hruby_low.rb', line 5412 def use_name?(*names) # Recurse on the expressions. return @expressions.any? { |expr| expr.use_name?(*names) } end |