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_low2hdr.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 Hparent

#parent

Instance Method Summary collapse

Methods included from Ltype

included, #ltype?

Methods inherited from Type

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

Methods included from Low2Symbol

#to_sym

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+.



1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
# File 'lib/HDLRuby/hruby_low.rb', line 1774

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+.



1829
1830
1831
1832
1833
1834
1835
# File 'lib/HDLRuby/hruby_low.rb', line 1829

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)



1916
1917
1918
1919
1920
1921
1922
1923
# File 'lib/HDLRuby/hruby_low.rb', line 1916

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)


1908
1909
1910
# File 'lib/HDLRuby/hruby_low.rb', line 1908

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.



1887
1888
1889
# File 'lib/HDLRuby/hruby_low.rb', line 1887

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.



1840
1841
1842
1843
1844
1845
# File 'lib/HDLRuby/hruby_low.rb', line 1840

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.



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

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.



1858
1859
1860
1861
1862
1863
1864
1865
# File 'lib/HDLRuby/hruby_low.rb', line 1858

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)


1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
# File 'lib/HDLRuby/hruby_low.rb', line 1795

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)


1929
1930
1931
1932
# File 'lib/HDLRuby/hruby_low.rb', line 1929

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.



1819
1820
1821
# File 'lib/HDLRuby/hruby_low.rb', line 1819

def get_all_types
    return @types.clone
end

#get_type(index) ⇒ Object

Gets a sub type by +index+.



1824
1825
1826
# File 'lib/HDLRuby/hruby_low.rb', line 1824

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

#hashObject

Hash function.



1809
1810
1811
# File 'lib/HDLRuby/hruby_low.rb', line 1809

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)



1895
1896
1897
1898
1899
1900
1901
1902
# File 'lib/HDLRuby/hruby_low.rb', line 1895

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)


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

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 C text of the equivalent HDLRuby code. +level+ is the hierachical level of the object.

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



558
559
560
561
562
563
# File 'lib/HDLRuby/hruby_low2c.rb', line 558

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

Generates the text of the equivalent hdr text. +level+ is the hierachical level of the object.



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

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

#to_highObject

Creates a new high type tuple.



109
110
111
112
# File 'lib/HDLRuby/hruby_low2high.rb', line 109

def to_high
    return HDLRuby::High::TypeTuple.new(self.name,self.direction,
                        *self.each_type.map { |typ| typ.to_high })
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.



713
714
715
716
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 713

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)


1814
1815
1816
# File 'lib/HDLRuby/hruby_low.rb', line 1814

def types?
    return true
end

#widthObject

Gets the bitwidth.



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

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