Class: HDLRuby::Low::TypeTuple

Inherits:
Type
  • Object
show all
Includes:
Ltype
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_low2high.rb,
lib/HDLRuby/hruby_low_mutable.rb,
lib/HDLRuby/hruby_low_skeleton.rb,
lib/HDLRuby/hruby_low_without_namespace.rb

Overview

Extends the TypeTuple class with functionality for breaking hierarchical types.

Direct Known Subclasses

High::TypeTuple

Constant Summary

Constants included from Low2Symbol

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

Instance Attribute Summary

Attributes inherited from Type

#name

Attributes included from Hdecorator

#hdr_id

Attributes included from Hparent

#parent

Instance Method Summary collapse

Methods included from Ltype

included, #ltype?

Methods inherited from Type

#boolean?, #fixed?, #float?, #leaf?, #range?, #set_name!, #signed?, #struct?, #to_vector, #to_verilog, #unsigned?, #vector?

Methods included from Low2Symbol

#to_sym

Methods included from Hdecorator

decorate_parent_id, dump, each, each_with_property, get, included, load, #properties

Methods included from Hparent

#scope

Constructor Details

#initialize(name, direction, *content) ⇒ TypeTuple

Creates a new tuple type named +name+ width +direction+ and whose sub types are given by +content+.



1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
# File 'lib/HDLRuby/hruby_low.rb', line 1749

def initialize(name,direction,*content)
    # Initialize the type.
    super(name)

    # Set the direction.
    @direction = direction.to_sym
    unless [:little, :big].include?(@direction)
        raise AnyError, "Invalid direction for a type: #{direction}"
    end

    # Check and set the content.
    content.each do |sub|
        unless sub.is_a?(Type) then
            raise AnyError, "Invalid class for a type: #{sub.class}"
        end
    end
    @types = content
end

Instance Method Details

#add_type(type) ⇒ Object

Adds a sub +type+.



1804
1805
1806
1807
1808
1809
1810
# File 'lib/HDLRuby/hruby_low.rb', line 1804

def add_type(type)
    unless type.is_a?(Type) then
        raise AnyError, 
              "Invalid class for a type: #{type.class} (#{type})"
    end
    @types << type
end

#baseObject

Gets the base type.

NOTE: only valid if the tuple is regular (i.e., all its sub types are identical)



1891
1892
1893
1894
1895
1896
1897
1898
# File 'lib/HDLRuby/hruby_low.rb', line 1891

def base
    if regular? then
        # Regular tuple, return the type of its first element.
        return @types[0]
    else
        raise AnyError, "No base type for type #{self}"
    end
end

#base?Boolean

Tells if the type has a base.

NOTE: only if the tuple is regular (i.e., all its sub types are identical)

Returns:

  • (Boolean)


1883
1884
1885
# File 'lib/HDLRuby/hruby_low.rb', line 1883

def base?
    return regular?
end

#break_types!(types) ⇒ Object

Breaks the hierarchical types into sequences of type definitions. Assumes to_upper_space! has been called before. +types+ include the resulting types.



337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 337

def break_types!(types)
    self.map_types! do |sub|
        if sub.is_a?(TypeVector) || sub.is_a?(TypeTuple) ||
                sub.is_a?(TypeStruct) then
            # Need to break
            # First recurse on the sub.
            nsub = sub.break_types!(types)
            # Maybe such a type already exists.
            ndef = types[sub]
            if ndef then
                # Yes, use it.
                ndef.clone
            else
                # No change it to a type definition
                ndef = TypeDef.new(HDLRuby.uniq_name,nsub)
                # And add it to the types by structure.
                types[nsub] = ndef
                nsub
            end
        end
    end
    return self
end

#delete_type!(type) ⇒ Object

Deletes a type.



334
335
336
337
338
339
340
341
342
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 334

def delete_type!(type)
    if @types.include?(type) then
        # The type is present, delete it.
        @types.delete(type)
        # And remove its parent.
        type.parent = nil
    end
    type
end

#directionObject

Get the direction of the type, little or big endian.



1862
1863
1864
# File 'lib/HDLRuby/hruby_low.rb', line 1862

def direction
    return @direction
end

#each(&ruby_block) ⇒ Object

Iterates over the sub name/type pair.

Returns an enumerator if no ruby block is given.



1815
1816
1817
1818
1819
1820
# File 'lib/HDLRuby/hruby_low.rb', line 1815

def each(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each) unless ruby_block
    # A ruby block? Apply it on each input signal instance.
    @types.each(&ruby_block)
end

#each_type(&ruby_block) ⇒ Object

Iterates over the sub types.

Returns an enumerator if no ruby block is given.



1825
1826
1827
1828
1829
1830
# File 'lib/HDLRuby/hruby_low.rb', line 1825

def each_type(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_type) unless ruby_block
    # A ruby block? Apply it on each input signal instance.
    @types.each(&ruby_block)
end

#each_type_deep(&ruby_block) ⇒ Object Also known as: each_deep

Iterates over the types deeply if any.



1833
1834
1835
1836
1837
1838
1839
1840
# File 'lib/HDLRuby/hruby_low.rb', line 1833

def each_type_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_type_deep) unless ruby_block
    # A ruby block? First apply it to current.
    ruby_block.call(self)
    # And recurse on the sub types.
    @types.each { |type| type.each_type_deep(&ruby_block) }
end

#eql?(obj) ⇒ Boolean

Comparison for hash: structural comparison.

Returns:

  • (Boolean)


1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
# File 'lib/HDLRuby/hruby_low.rb', line 1770

def eql?(obj)
    # General type comparison.
    return false unless super(obj)
    # Specific comparison.
    idx = 0
    obj.each_type do |type|
        return false unless @types[idx].eql?(type)
        idx += 1
    end
    return false unless idx == @types.size
    return true
end

#equivalent?(type) ⇒ Boolean

Tell if +type+ is equivalent to current type.

NOTE: type can be compatible while not being equivalent, please refer to hruby_types.rb for type compatibility.

Returns:

  • (Boolean)


1904
1905
1906
1907
# File 'lib/HDLRuby/hruby_low.rb', line 1904

def equivalent?(type)
    return (type.is_a?(TypeTuple) and
            !@types.zip(type.types).index {|t0,t1| !t0.equivalent?(t1) })
end

#get_all_typesObject

Gets an array containing all the syb types.



1794
1795
1796
# File 'lib/HDLRuby/hruby_low.rb', line 1794

def get_all_types
    return @types.clone
end

#get_type(index) ⇒ Object

Gets a sub type by +index+.



1799
1800
1801
# File 'lib/HDLRuby/hruby_low.rb', line 1799

def get_type(index)
    return @types[index.to_i]
end

#hashObject

Hash function.



1784
1785
1786
# File 'lib/HDLRuby/hruby_low.rb', line 1784

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

#map_types!(&ruby_block) ⇒ Object

Maps on the sub types.



329
330
331
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 329

def map_types!(&ruby_block)
    @types.map(&ruby_block)
end

#rangeObject

Gets the range of the type.

NOTE: only valid if the tuple is regular (i.e., all its sub types are identical)



1870
1871
1872
1873
1874
1875
1876
1877
# File 'lib/HDLRuby/hruby_low.rb', line 1870

def range
    if regular? then
        # Regular tuple, return its range as if it was an array.
        return 0..@types.size-1
    else
        raise AnyError, "No range for type #{self}"
    end
end

#regular?Boolean

Tell if the tuple is regular, i.e., all its sub types are equivalent.

NOTE: empty tuples are assumed not to be regular.

Returns:

  • (Boolean)


1847
1848
1849
1850
1851
1852
1853
1854
# File 'lib/HDLRuby/hruby_low.rb', line 1847

def regular?
    return false if @types.empty?
    t0 = @types[0]
    @types[1..-1].each do |type|
        return false unless t0.equivalent?(type)
    end
    return true
end

#to_c(level = 0) ⇒ Object

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

NOTE: type tuples are converted to bit vector of their contents.



551
552
553
554
555
556
# File 'lib/HDLRuby/hruby_low2c.rb', line 551

def to_c(level = 0)
    # return "get_type_tuple(#{self.each.to_a.join(",") do |type|
    #    type.to_c(level+1)
    # end})"
    return self.to_vector.to_c(level)
end

#to_high(level = 0) ⇒ Object

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



213
214
215
216
217
218
219
220
221
222
# File 'lib/HDLRuby/hruby_low2high.rb', line 213

def to_high(level = 0)
    # The resulting string.
    res = "["
    # Generate each sub type.
    res << self.each_type.map { |type| type.to_high(level) }.join(", ")
    # Close the tuple.
    res << "]"
    # Return the result.
    return res
end

#to_vhdl(level = 0) ⇒ Object

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

NOTE: type tuples are converted to bit vector of their contents.



703
704
705
706
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 703

def to_vhdl(level = 0)
    # raise AnyError, "Tuple types are not supported in VHDL, please convert them to Struct types using Low::tuple2struct from HDLRuby/hruby_low_witout_tuple."
    return self.to_vector.to_vhdl(level)
end

#types?Boolean

Tells if the type has sub types.

Returns:

  • (Boolean)


1789
1790
1791
# File 'lib/HDLRuby/hruby_low.rb', line 1789

def types?
    return true
end

#widthObject

Gets the bitwidth.



1857
1858
1859
# File 'lib/HDLRuby/hruby_low.rb', line 1857

def width
    return @types.reduce(0) { |sum,type| sum + type.width }
end