Class: HDLRuby::Low::TypeStruct

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 TypeStruct class with functionality for breaking hierarchical types.

Direct Known Subclasses

High::TypeStruct

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

#base, #base?, #boolean?, #direction, #fixed?, #float?, #hierarchical?, #leaf?, #max, #min, #range, #range?, #regular?, #set_name!, #signed?, #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) ⇒ TypeStruct

Creates a new structure type named +name+ with +direction+ and whose hierachy is given by +content+.



2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
# File 'lib/HDLRuby/hruby_low.rb', line 2026

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 = Hash[content]
    @types = content.map do |k,v|
        unless v.is_a?(Type) then
            raise AnyError, "Invalid class for a type: #{v.class}"
        end
        [ k.to_sym, v ]
    end.to_h
end

Instance Method Details

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



375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 375

def break_types!(types)
    self.map_types! do |sub|
        if sub.is_a?(TypeVector) || sub.is_a?(TypeStruct) ||
                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!(key) ⇒ Object

Deletes a sub type by +key+.



368
369
370
371
372
373
374
375
376
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 368

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

#each(&ruby_block) ⇒ Object

Iterates over the sub name/type pair.

Returns an enumerator if no ruby block is given.



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

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_name(&ruby_block) ⇒ Object

Iterates over the sub type names.

Returns an enumerator if no ruby block is given.



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

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

#each_type(&ruby_block) ⇒ Object

Iterates over the sub types.

Returns an enumerator if no ruby block is given.



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

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_value(&ruby_block)
end

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

Iterates over the types deeply if any.



2116
2117
2118
2119
2120
2121
2122
2123
# File 'lib/HDLRuby/hruby_low.rb', line 2116

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_value { |type| type.each_type_deep(&ruby_block) }
end

#eql?(obj) ⇒ Boolean

Comparison for hash: structural comparison.

Returns:

  • (Boolean)


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

def eql?(obj)
    # General type comparison.
    return false unless super(obj)
    # Specific comparison.
    idx = 0
    obj.each_key do |name|
        return false unless @types[name].eql?(obj.get_type(name))
        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)


2172
2173
2174
2175
2176
2177
# File 'lib/HDLRuby/hruby_low.rb', line 2172

def equivalent?(type)
    return (type.is_a?(TypeStruct) and
            !@types.to_a.zip(type.types.to_a).index do |t0,t1|
        t0[0] != t1[0] or !t0[1].equivalent?(t1[1])
    end)
end

#get_all_typesObject

Gets an array containing all the syb types.



2076
2077
2078
# File 'lib/HDLRuby/hruby_low.rb', line 2076

def get_all_types
    return @types.values
end

#get_type(name) ⇒ Object

Gets a sub type by +name+.



2081
2082
2083
# File 'lib/HDLRuby/hruby_low.rb', line 2081

def get_type(name)
    return @types[name.to_sym]
end

#hashObject

Hash function.



2061
2062
2063
# File 'lib/HDLRuby/hruby_low.rb', line 2061

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

#map_types!(&ruby_block) ⇒ Object

Maps on the sub types.



363
364
365
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 363

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

#struct?Boolean

Tells if the type has named sub types.

Returns:

  • (Boolean)


2066
2067
2068
# File 'lib/HDLRuby/hruby_low.rb', line 2066

def struct?
    return true
end

#to_c(res, level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby code. +level+ is the hierachical level of the object. def to_c(level = 0)



642
643
644
645
646
647
648
649
650
# File 'lib/HDLRuby/hruby_low2c.rb', line 642

def to_c(res,level = 0)
    # return "get_type_struct(#{self.each.join(",") do |key,type|
    #     "\"#{key.to_s}\",#{type.to_c(level+1)}"
    # end})"
    res << "get_type_struct(#{self.each.join(",") do |key,type|
        "\"#{key.to_s}\",#{type.to_c("",level+1)}"
    end})"
    return res
end

#to_hdr(level = 0) ⇒ Object

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



230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 230

def to_hdr(level = 0)
    # The resulting string.
    res = "{ "
    # Generate each sub type.
    res << self.each.map do |key,type|
        "#{key}: " + type.to_hdr(level)
    end.join(", ")
    # Close the struct.
    res << " }"
    # Return the result.
    return res
end

#to_highObject

Creates a new high type struct.



119
120
121
122
# File 'lib/HDLRuby/hruby_low2high.rb', line 119

def to_high
    return HDLRuby::High::TypeString.new(self.name,self.direction,
                            self.each {|name,typ| [name,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.



724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 724

def to_vhdl(level = 0)
    # The resulting string.
    res = "record \n"
    # Generate each sub type.
    self.each do |key,type|
        res << " " * ((level+1)*3)
        res << Low2VHDL.vhdl_name(key)
        res << ": " << type.to_vhdl(level+1)
        res << ";\n"
    end
    res << " " * (level*3)
    # Close the record.
    res << "end record"
    # Return the result.
    return res
end

#types?Boolean

Tells if the type has sub types.

Returns:

  • (Boolean)


2071
2072
2073
# File 'lib/HDLRuby/hruby_low.rb', line 2071

def types?
    return true
end

#widthObject

Gets the bitwidth of the type, nil for undefined.

NOTE: must be redefined for specific types.



2130
2131
2132
# File 'lib/HDLRuby/hruby_low.rb', line 2130

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