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 collapse

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?, #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, dir, content) ⇒ TypeStruct

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



2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
# File 'lib/HDLRuby/hruby_low.rb', line 2135

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

    # Set the direction.
    @direction = dir.to_sym
    unless [:little, :big].include?(@direction)
        raise AnyError, "Invalid direction for a type: #{dir}"
    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 Attribute Details

#directionObject (readonly)

Returns the value of attribute direction.



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

def direction
  @direction
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.



2203
2204
2205
2206
2207
2208
# File 'lib/HDLRuby/hruby_low.rb', line 2203

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

Iterates over the keys.

Returns an enumerator if no ruby block is given.



2223
2224
2225
2226
2227
2228
# File 'lib/HDLRuby/hruby_low.rb', line 2223

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

#each_name(&ruby_block) ⇒ Object

Iterates over the sub type names.

Returns an enumerator if no ruby block is given.



2233
2234
2235
2236
2237
2238
# File 'lib/HDLRuby/hruby_low.rb', line 2233

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 name.
    @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.



2213
2214
2215
2216
2217
2218
# File 'lib/HDLRuby/hruby_low.rb', line 2213

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

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

Iterates over the types deeply if any.



2241
2242
2243
2244
2245
2246
2247
2248
# File 'lib/HDLRuby/hruby_low.rb', line 2241

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)


2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
# File 'lib/HDLRuby/hruby_low.rb', line 2156

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


2301
2302
2303
2304
2305
2306
# File 'lib/HDLRuby/hruby_low.rb', line 2301

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.



2186
2187
2188
# File 'lib/HDLRuby/hruby_low.rb', line 2186

def get_all_types
    return @types.values
end

#get_type(name) ⇒ Object

Gets a sub type by +name+. NOTE: +name+ can also be an index.



2192
2193
2194
2195
2196
2197
2198
# File 'lib/HDLRuby/hruby_low.rb', line 2192

def get_type(name)
    if name.respond_to?(:to_sym) then
        return @types[name.to_sym]
    else
        return @types.values[name.to_i]
    end
end

#hashObject

Hash function.



2171
2172
2173
# File 'lib/HDLRuby/hruby_low.rb', line 2171

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)


2176
2177
2178
# File 'lib/HDLRuby/hruby_low.rb', line 2176

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)



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

def to_c(res,level = 0)
    # res << "get_type_struct(#{self.each.map do |key,type|
    #     "\"#{key.to_s}\",#{type.to_c("",level+1)}"
    # end.join(",")})"
    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.



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)


2181
2182
2183
# File 'lib/HDLRuby/hruby_low.rb', line 2181

def types?
    return true
end

#widthObject

Gets the bitwidth of the type, nil for undefined.

NOTE: must be redefined for specific types.



2255
2256
2257
2258
2259
2260
2261
# File 'lib/HDLRuby/hruby_low.rb', line 2255

def width
    if @types.is_a?(Array) then
        return @types.reduce(0) {|sum,type| sum + type.width }
    else
        return @types.each_value.reduce(0) {|sum,type| sum + type.width }
    end
end