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_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?, #leaf?, #range, #range?, #regular?, #set_name!, #signed?, #to_vector, #to_verilog, #unsigned?

Methods included from Low2Symbol

#to_sym

Methods included from Hparent

#scope

Constructor Details

#initialize(name, direction, content) ⇒ TypeStruct

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



1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
# File 'lib/HDLRuby/hruby_low.rb', line 1821

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.



369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 369

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.



356
357
358
359
360
361
362
363
364
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 356

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.



1883
1884
1885
1886
1887
1888
# File 'lib/HDLRuby/hruby_low.rb', line 1883

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.



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

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.



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

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

Iterates over the types deeply if any.



1911
1912
1913
1914
1915
1916
1917
1918
# File 'lib/HDLRuby/hruby_low.rb', line 1911

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)


1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
# File 'lib/HDLRuby/hruby_low.rb', line 1842

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)


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

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.



1871
1872
1873
# File 'lib/HDLRuby/hruby_low.rb', line 1871

def get_all_types
    return @types.values
end

#get_type(name) ⇒ Object

Gets a sub type by name.



1876
1877
1878
# File 'lib/HDLRuby/hruby_low.rb', line 1876

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

#hashObject

Hash function.



1856
1857
1858
# File 'lib/HDLRuby/hruby_low.rb', line 1856

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

#map_types!(&ruby_block) ⇒ Object

Maps on the sub types.



351
352
353
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 351

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

#struct?Boolean

Tells if the type has named sub types.

Returns:

  • (Boolean)


1861
1862
1863
# File 'lib/HDLRuby/hruby_low.rb', line 1861

def struct?
    return true
end

#to_c(level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. level is the hierachical level of the object.



564
565
566
567
568
# File 'lib/HDLRuby/hruby_low2c.rb', line 564

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

#to_high(level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. level is the hierachical level of the object.



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

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

#to_vhdl(level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. level is the hierachical level of the object.



714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 714

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)


1866
1867
1868
# File 'lib/HDLRuby/hruby_low.rb', line 1866

def types?
    return true
end

#widthObject

Gets the bitwidth of the type, nil for undefined.

NOTE: must be redefined for specific types.



1923
1924
1925
# File 'lib/HDLRuby/hruby_low.rb', line 1923

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