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

Methods included from Hparent

#scope

Constructor Details

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

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



4394
4395
4396
4397
4398
4399
4400
# File 'lib/HDLRuby/hruby_low.rb', line 4394

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.



4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
# File 'lib/HDLRuby/hruby_low.rb', line 4423

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.



247
248
249
250
251
252
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 247

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)



4466
4467
4468
4469
# File 'lib/HDLRuby/hruby_low.rb', line 4466

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

#delete_expression!(expression) ⇒ Object

Delete an expression.



1606
1607
1608
1609
1610
1611
1612
1613
1614
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1606

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.



4439
4440
4441
4442
4443
4444
# File 'lib/HDLRuby/hruby_low.rb', line 4439

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.



4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
# File 'lib/HDLRuby/hruby_low.rb', line 4448

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)


4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
# File 'lib/HDLRuby/hruby_low.rb', line 4403

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
317
318
319
320
# 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.
        # 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

#hashObject

Hash function.



4418
4419
4420
# File 'lib/HDLRuby/hruby_low.rb', line 4418

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

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

Maps on the expression.



1595
1596
1597
1598
1599
1600
1601
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1595

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.



1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
# File 'lib/HDLRuby/hruby_low2c.rb', line 1787

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



1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
# File 'lib/HDLRuby/hruby_verilog.rb', line 1649

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.



1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1350

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

#use_name?(*names) ⇒ Boolean

Tell if the expression includes a signal whose name is one of +names+.

Returns:

  • (Boolean)


4460
4461
4462
4463
# File 'lib/HDLRuby/hruby_low.rb', line 4460

def use_name?(*names)
    # Recurse on the expressions.
    return @expressions.any? { |expr| expr.use_name?(*names) }
end