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

Constructor Details

#initialize(name, direction, content) ⇒ TypeStruct

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



1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
# File 'lib/HDLRuby/hruby_low.rb', line 1785

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



329
330
331
332
333
334
335
336
337
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 329

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.



1847
1848
1849
1850
1851
1852
# File 'lib/HDLRuby/hruby_low.rb', line 1847

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.



1867
1868
1869
1870
1871
1872
# File 'lib/HDLRuby/hruby_low.rb', line 1867

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.



1857
1858
1859
1860
1861
1862
# File 'lib/HDLRuby/hruby_low.rb', line 1857

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.



1875
1876
1877
1878
1879
1880
1881
1882
# File 'lib/HDLRuby/hruby_low.rb', line 1875

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)


1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
# File 'lib/HDLRuby/hruby_low.rb', line 1806

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)


1929
1930
1931
1932
1933
1934
# File 'lib/HDLRuby/hruby_low.rb', line 1929

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.



1835
1836
1837
# File 'lib/HDLRuby/hruby_low.rb', line 1835

def get_all_types
    return @types.values
end

#get_type(name) ⇒ Object

Gets a sub type by +name+.



1840
1841
1842
# File 'lib/HDLRuby/hruby_low.rb', line 1840

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

#hashObject

Hash function.



1820
1821
1822
# File 'lib/HDLRuby/hruby_low.rb', line 1820

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

#map_types!(&ruby_block) ⇒ Object

Maps on the sub types.



324
325
326
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 324

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

#struct?Boolean

Tells if the type has named sub types.

Returns:

  • (Boolean)


1825
1826
1827
# File 'lib/HDLRuby/hruby_low.rb', line 1825

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.



559
560
561
562
563
# File 'lib/HDLRuby/hruby_low2c.rb', line 559

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.



701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 701

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)


1830
1831
1832
# File 'lib/HDLRuby/hruby_low.rb', line 1830

def types?
    return true
end

#widthObject

Gets the bitwidth of the type, nil for undefined.

NOTE: must be redefined for specific types.



1887
1888
1889
# File 'lib/HDLRuby/hruby_low.rb', line 1887

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