Class: HDLRuby::Low::TypeVector

Inherits:
Type
  • Object
show all
Defined in:
lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_viz.rb,
lib/HDLRuby/hruby_low2c.rb,
lib/HDLRuby/hruby_low2hdr.rb,
lib/HDLRuby/hruby_low2vhd.rb,
lib/HDLRuby/hruby_verilog.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

Describes a vector type.

Direct Known Subclasses

High::TypeVector, TypeFloat, TypeSigned, TypeUnsigned

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 inherited from Type

#boolean?, #hierarchical?, #leaf?, #range?, #regular?, #set_name!, #struct?, #to_vector, #types?

Methods included from Low2Symbol

#to_sym

Methods included from Hparent

#absolute_ref, #hierarchy, #no_parent!, #scope

Constructor Details

#initialize(name, base, range) ⇒ TypeVector

Creates a new vector type named +name+ from +base+ type and with +range+. NOTE: if +range+ is a positive integer it is converted to (range-1)..0, if it is a negative integer it is converted to 0..(-range-1)



1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
# File 'lib/HDLRuby/hruby_low.rb', line 1833

def initialize(name,base,range)
    # Initialize the type.
    super(name)

    # Check and set the base
    unless base.is_a?(Type)
        raise AnyError,
              "Invalid class for VectorType base: #{base.class}."
    end
    @base = base

    # Check and set the range.
    if range.respond_to?(:to_i) then
        # Integer case: convert to 0..(range-1).
        range = range > 0 ? (range-1)..0 : 0..(-range-1)
    elsif
        # Other cases: assume there is a first and a last to create
        # the range.
        range = range.first..range.last
    end
    @range = range
end

Instance Attribute Details

#baseObject (readonly)

The base type of the vector



1813
1814
1815
# File 'lib/HDLRuby/hruby_low.rb', line 1813

def base
  @base
end

#rangeObject (readonly)

The range of the vector.



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

def range
  @range
end

Instance Method Details

#base?Boolean

Tells if the type has a base.

Returns:

  • (Boolean)


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

def base?
    return true
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.



316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 316

def break_types!(types)
    if self.base.is_a?(TypeVector) || self.base.is_a?(TypeTuple) ||
       self.base.is_a?(TypeStruct) then
        # Need to break
        # First recurse on the base.
        nbase = self.base.break_types!(types)
        # # Maybe such a type already exists.
        # ndef = types[nbase]
        # if ndef then
        #     # Yes, use it.
        #     self.set_base!(ndef.clone)
        # else
        #     # No change it to a type definition
        #     ndef = TypeDef.new(HDLRuby.uniq_name,nbase)
        #     self.set_base!(ndef)
        #     # And add it to the types by structure.
        #     types[nbase] = ndef
        # end
        # Sets the base.
        self.set_base!(nbase)
        # And create a new type from current type.
        # Maybe the new type already exists.
        ndef = types[self]
        return ndef if ndef # Yes, already exists.
        # No, create and register a new typedef.
        ndef = TypeDef.new(HDLRuby.uniq_name,self)
        types[self] = ndef
        return ndef
    end
    return self
end

#dirObject

Gets the direction of the range.



1911
1912
1913
# File 'lib/HDLRuby/hruby_low.rb', line 1911

def dir
    return (@range.last - @range.first)
end

#directionObject

Get the direction of the type, little or big endian.



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

def direction
    return @range.first < @range.last ? :big : :little
end

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

Iterates over the types deeply if any.



1956
1957
1958
1959
1960
1961
1962
1963
# File 'lib/HDLRuby/hruby_low.rb', line 1956

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 base.
    @base.each_type_deep(&ruby_block)
end

#eql?(obj) ⇒ Boolean

Comparison for hash: structural comparison.

Returns:

  • (Boolean)


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

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


1939
1940
1941
1942
1943
# File 'lib/HDLRuby/hruby_low.rb', line 1939

def equivalent?(type)
    return (type.is_a?(TypeVector) and
            @range == type.range
            @base.equivalent?(type.base) )
end

#fixed?Boolean

Tells if the type is fixed point.

Returns:

  • (Boolean)


1926
1927
1928
# File 'lib/HDLRuby/hruby_low.rb', line 1926

def fixed?
    return @base.signed?
end

#float?Boolean

Tells if the type is floating point.

Returns:

  • (Boolean)


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

def float?
    return @base.float?
end

#hashObject

Hash function.



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

def hash
    return [super,@base,@range].hash
end

#maxObject

Gets the type max value if any.



1887
1888
1889
1890
1891
1892
1893
# File 'lib/HDLRuby/hruby_low.rb', line 1887

def max
    if (self.signed?) then
        return (2**(self.width-1))-1
    else
        return (2**(self.width))-1
    end
end

#minObject

Gets the type min value if any. Default: not defined.



1897
1898
1899
1900
1901
1902
1903
# File 'lib/HDLRuby/hruby_low.rb', line 1897

def min
    if (self.signed?) then
        return -(2**(self.width-1))
    else
        return 0
    end
end

#set_base!(type) ⇒ Object

Sets the +base+ type.



301
302
303
304
305
306
307
308
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 301

def set_base!(type)
    # Check and set the base
    unless type.is_a?(Type)
        raise AnyError,
              "Invalid class for VectorType base: #{base.class}."
    end
    @base = type
end

#set_range!(ranage) ⇒ Object

Sets the +range+.



311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 311

def set_range!(ranage)
    # Check and set the range.
    if range.respond_to?(:to_i) then
        # Integer case: convert to 0..(range-1).
        range = (range-1)..0
    elsif
        # Other cases: assume there is a first and a last to create
        # the range.
        range = range.first..range.last
    end
    @range = range
end

#signed?Boolean

Tells if the type signed.

Returns:

  • (Boolean)


1916
1917
1918
# File 'lib/HDLRuby/hruby_low.rb', line 1916

def signed?
    return @base.signed?
end

#sizeObject

Gets the size of the type in number of base elements.



1873
1874
1875
# File 'lib/HDLRuby/hruby_low.rb', line 1873

def size
    return (@range.first.to_i - @range.last.to_i).abs + 1
end

#to_c(res, level = 0) ⇒ Object

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



612
613
614
615
616
617
618
619
620
# File 'lib/HDLRuby/hruby_low2c.rb', line 612

def to_c(res,level = 0)
    # The resulting string.
    # return "get_type_vector(#{self.base.to_c(level+1)}," +
    #        "#{self.size})"
    res << "get_type_vector("
    self.base.to_c(res,level+1)
    res << ",#{self.size})"
    return res
end

#to_hdr(level = 0) ⇒ Object

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



197
198
199
200
201
202
203
204
205
206
207
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 197

def to_hdr(level = 0)
    # The resulting string.
    res = ""
    # Generate the base.
    res << self.base.to_hdr(level)
    # Generate the range.
    res << "[" << self.range.first.to_hdr(level) << ".." <<
    self.range.last.to_hdr(level) << "]"
    # Return the result.
    return res
end

#to_highObject

Creates a new high type vector.



84
85
86
87
88
# File 'lib/HDLRuby/hruby_low2high.rb', line 84

def to_high
    return HDLRuby::High::TypeVector.new(self.name,
                                             self.base.to_high,
                                             self.range)
end

#to_verilogObject

Converts the system to Verilog code.



1563
1564
1565
1566
1567
1568
1569
# File 'lib/HDLRuby/hruby_verilog.rb', line 1563

def to_verilog
    # if self.base.name.to_s != "bit"
    if VERILOG_BASE_TYPES.include?(self.base.name.to_s)
        return " #{self.base.name.to_s}[#{self.range.first}:#{self.range.last}]"
    end
    return " [#{self.range.first}:#{self.range.last}]"
end

#to_vhdl(level = 0) ⇒ Object

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



654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 654

def to_vhdl(level = 0)
    # The resulting string.
    res = ""
    # Depending on the base.
    if self.base.class < Type then
        # The base is not a leaf, therefore the type is a VHDL array.
        # NOTE: array are always valid if used in type definition,
        # it is assumed that break_types! from
        # hruby_low_without_namespace.rb is used.
        res << "array ("
        res << self.range.first.to_vhdl(level)
        if self.range.first >= self.range.last then
            res << " downto "
        else
            res << " to "
        end
        res << self.range.last.to_vhdl(level)
        res << ") of "
        # Now generate the base.
        res << base.to_vhdl(level+1)
    else
        # The base is a leaf, therefore the type is VHDL vector.
        # Depending on the base name.
        case(base.name)
        when :bit
            # std_logic_vector.
            res << "std_logic_vector"
        when :signed
            res << "signed"
        when :unsigned
            res << "unsigned"
        else
            res << Low2VHDL.vhdl_name(self.base.name)
        end
        # Now the range
        res << "("
        res << self.range.first.to_vhdl(level)
        left = self.range.first
        right = self.range.last
        left = left.content if left.is_a?(Value)
        right = right.content if right.is_a?(Value)
        if left >= right then
            res << " downto "
        else
            res << " to "
        end
        res << self.range.last.to_vhdl(level)
        res << ")"
    end
    # Return the result.
    return res
end

#to_viz_nameObject

Convert to a name usable in a Viz representation.



5039
5040
5041
5042
5043
# File 'lib/HDLRuby/hruby_viz.rb', line 5039

def to_viz_name
  fstr = self.range.first.is_a?(HDLRuby::Low::Value) ? self.range.first.content.to_s : self.range.first.to_s
  lstr = self.range.last.is_a?(HDLRuby::Low::Value) ? self.range.last.content.to_s : self.range.last.to_s
  return self.base.to_viz_name + "[" + fstr + ".." + lstr + "]"
end

#unsigned?Boolean

Tells if the type is unsigned.

Returns:

  • (Boolean)


1921
1922
1923
# File 'lib/HDLRuby/hruby_low.rb', line 1921

def unsigned?
    return @base.unsigned?
end

#vector?Boolean

Tells if the type of of vector kind.

Returns:

  • (Boolean)


1816
1817
1818
# File 'lib/HDLRuby/hruby_low.rb', line 1816

def vector?
    return true
end

#widthObject

Gets the bitwidth of the type, nil for undefined.

NOTE: must be redefined for specific types.



1880
1881
1882
1883
1884
# File 'lib/HDLRuby/hruby_low.rb', line 1880

def width
    first = @range.first.to_i
    last  = @range.last.to_i
    return @base.width * ((first-last).abs + 1)
end