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 = [])
5312 5313 5314 5315 5316 5317 5318 5319 |
# File 'lib/HDLRuby/hruby_low.rb', line 5312 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.
5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 |
# File 'lib/HDLRuby/hruby_low.rb', line 5366 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)
5409 5410 5411 5412 |
# File 'lib/HDLRuby/hruby_low.rb', line 5409 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.
5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 |
# File 'lib/HDLRuby/hruby_low.rb', line 5332 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.
5382 5383 5384 5385 5386 5387 |
# File 'lib/HDLRuby/hruby_low.rb', line 5382 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.
5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 |
# File 'lib/HDLRuby/hruby_low.rb', line 5391 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.
5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 |
# File 'lib/HDLRuby/hruby_low.rb', line 5346 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.
5361 5362 5363 |
# File 'lib/HDLRuby/hruby_low.rb', line 5361 def hash return [super,@expressions].hash end |
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.)
5322 5323 5324 5325 5326 5327 |
# File 'lib/HDLRuby/hruby_low.rb', line 5322 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.
2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2577 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
1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1782 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+.
5403 5404 5405 5406 |
# File 'lib/HDLRuby/hruby_low.rb', line 5403 def use_name?(*names) # Recurse on the expressions. return @expressions.any? { |expr| expr.use_name?(*names) } end |