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



1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
# File 'lib/HDLRuby/hruby_low.rb', line 1965

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



2021
2022
2023
2024
2025
2026
2027
# File 'lib/HDLRuby/hruby_low.rb', line 2021

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)



2108
2109
2110
2111
2112
2113
2114
2115
# File 'lib/HDLRuby/hruby_low.rb', line 2108

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)


2100
2101
2102
# File 'lib/HDLRuby/hruby_low.rb', line 2100

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.



2079
2080
2081
# File 'lib/HDLRuby/hruby_low.rb', line 2079

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.



2032
2033
2034
2035
2036
2037
# File 'lib/HDLRuby/hruby_low.rb', line 2032

def each(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each) unless ruby_block
    # A ruby block? Apply it on each sub name/type pair.
    @types.each(&ruby_block)
end

#each_type(&ruby_block) ⇒ Object

Iterates over the sub types.

Returns an enumerator if no ruby block is given.



2042
2043
2044
2045
2046
2047
# File 'lib/HDLRuby/hruby_low.rb', line 2042

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 sub type.
    @types.each(&ruby_block)
end

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

Iterates over the types deeply if any.



2050
2051
2052
2053
2054
2055
2056
2057
# File 'lib/HDLRuby/hruby_low.rb', line 2050

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)


1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
# File 'lib/HDLRuby/hruby_low.rb', line 1986

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)


2121
2122
2123
2124
# File 'lib/HDLRuby/hruby_low.rb', line 2121

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.



2011
2012
2013
# File 'lib/HDLRuby/hruby_low.rb', line 2011

def get_all_types
    return @types.clone
end

#get_type(index) ⇒ Object

Gets a sub type by +index+.



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

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

#hashObject

Hash function.



2001
2002
2003
# File 'lib/HDLRuby/hruby_low.rb', line 2001

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)



2087
2088
2089
2090
2091
2092
2093
2094
# File 'lib/HDLRuby/hruby_low.rb', line 2087

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)


2064
2065
2066
2067
2068
2069
2070
2071
# File 'lib/HDLRuby/hruby_low.rb', line 2064

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)



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

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)


2006
2007
2008
# File 'lib/HDLRuby/hruby_low.rb', line 2006

def types?
    return true
end

#widthObject

Gets the bitwidth.



2074
2075
2076
# File 'lib/HDLRuby/hruby_low.rb', line 2074

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