Class: HDLRuby::Low::Concat

Inherits:
Expression
  • Object
show all
Includes:
MutableConcat
Defined in:
lib/HDLRuby/hruby_db.rb,
lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_low2c.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

Overview

Extends the Concat class with functionality for converting booleans in assignments to select operators.

Direct Known Subclasses

High::Concat

Constant Summary

Constants included from Low2Symbol

Low2Symbol::Low2SymbolPrefix, Low2Symbol::Low2SymbolTable, Low2Symbol::Symbol2LowTable

Instance Attribute Summary

Attributes inherited from Expression

#type

Attributes included from Hparent

#parent

Instance Method Summary collapse

Methods included from MutableConcat

#replace_expressions!

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

#to_sym

Constructor Details

#initialize(type, expressions = []) ⇒ Concat

Creates a new concatenation with +type+ of several +expressions+ together.
def initialize(expressions = [])



4236
4237
4238
4239
4240
4241
4242
# File 'lib/HDLRuby/hruby_low.rb', line 4236

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.



4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
# File 'lib/HDLRuby/hruby_low.rb', line 4265

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_assign2selectObject

Converts booleans in assignments to select operators.



224
225
226
227
228
229
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 224

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

#cloneObject

Clones the concatenated expression (deeply)



4302
4303
4304
4305
# File 'lib/HDLRuby/hruby_low.rb', line 4302

def clone
    return Concat.new(@type,
                      @expressions.map {|expr| expr.clone } )
end

#delete_expression!(expression) ⇒ Object

Delete an expression.



1517
1518
1519
1520
1521
1522
1523
1524
1525
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1517

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_expression(&ruby_block) ⇒ Object Also known as: each_node

Iterates over the concatenated expressions.

Returns an enumerator if no ruby block is given.



4281
4282
4283
4284
4285
4286
# File 'lib/HDLRuby/hruby_low.rb', line 4281

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.



4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
# File 'lib/HDLRuby/hruby_low.rb', line 4290

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.

Returns:

  • (Boolean)


4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
# File 'lib/HDLRuby/hruby_low.rb', line 4245

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.



293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 293

def explicit_types(type = nil)
    # Is there a type to match?
    if type then
        # Yes, update the concat to the type.
        # 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.expressions.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.expressions.map do |expr|
            expr.explicit_types
        end)
    end
end

#hashObject

Hash function.



4260
4261
4262
# File 'lib/HDLRuby/hruby_low.rb', line 4260

def hash
    return [super,@expressions].hash
end

#map_expressions!(&ruby_block) ⇒ Object Also known as: map_nodes!

Maps on the expression.



1506
1507
1508
1509
1510
1511
1512
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1506

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(level = 0) ⇒ Object

Generates the C text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.



1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
# File 'lib/HDLRuby/hruby_low2c.rb', line 1756

def to_c(level = 0)
    # Gather the content to concat.
    expressions = self.each_expression.to_a
    # Create the resulting string.
    # res = " " * (level*3)
    res = "({\n"
    # Overrides the upper src0, src1, ..., and dst...
    # And allocates a new value for dst.
    res << (" " * ((level+1)*3))
    res << "Value #{expressions.size.times.map do |i| 
        "src#{i}"
    end.join(",")};\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(level+2)};\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"
    # 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

#to_high(level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +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_low2high.rb', line 631

def to_high(level = 0)
    # The resulting string.
    res = ""
    # Generate the header.
    res << "[ "
    # Generate the expressions.
    res << self.each_expression.map do |expression|
        expression.to_high(level+1)
    end.join(", ")
    # Close the select.
    res << " ]"
    # Return the resulting string.
    return res
end

#to_verilogObject



1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
# File 'lib/HDLRuby/hruby_verilog.rb', line 1532

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(type, level = 0) ⇒ 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.



1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1287

def to_vhdl(type,level = 0)
    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