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

#hierarchy, #no_parent!, #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+.



1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
# File 'lib/HDLRuby/hruby_low.rb', line 1858

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



1914
1915
1916
1917
1918
1919
1920
# File 'lib/HDLRuby/hruby_low.rb', line 1914

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)



2001
2002
2003
2004
2005
2006
2007
2008
# File 'lib/HDLRuby/hruby_low.rb', line 2001

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)


1993
1994
1995
# File 'lib/HDLRuby/hruby_low.rb', line 1993

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.



343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 343

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.



346
347
348
349
350
351
352
353
354
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 346

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.



1972
1973
1974
# File 'lib/HDLRuby/hruby_low.rb', line 1972

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.



1925
1926
1927
1928
1929
1930
# File 'lib/HDLRuby/hruby_low.rb', line 1925

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.



1935
1936
1937
1938
1939
1940
# File 'lib/HDLRuby/hruby_low.rb', line 1935

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.



1943
1944
1945
1946
1947
1948
1949
1950
# File 'lib/HDLRuby/hruby_low.rb', line 1943

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)


1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
# File 'lib/HDLRuby/hruby_low.rb', line 1879

def eql?(obj)
    # # General type comparison.
    # return false unless super(obj)
    return false unless obj.is_a?(TypeTuple)
    # 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)


2014
2015
2016
2017
# File 'lib/HDLRuby/hruby_low.rb', line 2014

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.



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

def get_all_types
    return @types.clone
end

#get_type(index) ⇒ Object

Gets a sub type by +index+.



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

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

#hashObject

Hash function.



1894
1895
1896
# File 'lib/HDLRuby/hruby_low.rb', line 1894

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

#map_types!(&ruby_block) ⇒ Object

Maps on the sub types.



341
342
343
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 341

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)



1980
1981
1982
1983
1984
1985
1986
1987
# File 'lib/HDLRuby/hruby_low.rb', line 1980

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)


1957
1958
1959
1960
1961
1962
1963
1964
# File 'lib/HDLRuby/hruby_low.rb', line 1957

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(res, 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. def to_c(level = 0)



628
629
630
631
632
# File 'lib/HDLRuby/hruby_low2c.rb', line 628

def to_c(res,level = 0)
    # return self.to_vector.to_c(level)
    self.to_vector.to_c(res,level)
    return res
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)


1899
1900
1901
# File 'lib/HDLRuby/hruby_low.rb', line 1899

def types?
    return true
end

#widthObject

Gets the bitwidth.



1967
1968
1969
# File 'lib/HDLRuby/hruby_low.rb', line 1967

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