Class: HDLRuby::Low::TypeVector

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_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

Extends the TypeVector class with functionality for breaking hierarchical types.

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 Hdecorator

#hdr_id

Attributes included from Hparent

#parent

Instance Method Summary collapse

Methods included from Ltype

included, #ltype?

Methods inherited from Type

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

Methods included from Low2Symbol

#to_sym

Methods included from Hdecorator

decorate_parent_id, dump, each, each_with_property, get, included, load, #properties

Methods included from Hparent

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



137
138
139
140
141
142
# File 'lib/HDLRuby/hruby_db.rb', line 137

def initialize(name,base,range)
    # Ensure base si a HDLRuby::Low type.
    base = Type.get(base)
    # Create the type.
    super(name,base,range)
end

Instance Attribute Details

#baseObject (readonly)

The base type of the vector



1553
1554
1555
# File 'lib/HDLRuby/hruby_low.rb', line 1553

def base
  @base
end

#rangeObject (readonly)

The range of the vector.



1566
1567
1568
# File 'lib/HDLRuby/hruby_low.rb', line 1566

def range
  @range
end

Instance Method Details

#base?Boolean

Tells if the type has a base.

Returns:

  • (Boolean)


1561
1562
1563
# File 'lib/HDLRuby/hruby_low.rb', line 1561

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.



297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 297

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.



1632
1633
1634
# File 'lib/HDLRuby/hruby_low.rb', line 1632

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

#directionObject

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



1627
1628
1629
# File 'lib/HDLRuby/hruby_low.rb', line 1627

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.



1677
1678
1679
1680
1681
1682
1683
1684
# File 'lib/HDLRuby/hruby_low.rb', line 1677

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)


1597
1598
1599
1600
1601
1602
1603
1604
1605
# File 'lib/HDLRuby/hruby_low.rb', line 1597

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)


1660
1661
1662
1663
1664
# File 'lib/HDLRuby/hruby_low.rb', line 1660

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)


1647
1648
1649
# File 'lib/HDLRuby/hruby_low.rb', line 1647

def fixed?
    return @base.signed?
end

#float?Boolean

Tells if the type is floating point.

Returns:

  • (Boolean)


1652
1653
1654
# File 'lib/HDLRuby/hruby_low.rb', line 1652

def float?
    return @base.float?
end

#hashObject

Hash function.



1608
1609
1610
# File 'lib/HDLRuby/hruby_low.rb', line 1608

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

#set_base!(type) ⇒ Object

Sets the +base+ type.



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

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



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

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)


1637
1638
1639
# File 'lib/HDLRuby/hruby_low.rb', line 1637

def signed?
    return @base.signed?
end

#sizeObject

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



1613
1614
1615
# File 'lib/HDLRuby/hruby_low.rb', line 1613

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

#to_c(level = 0) ⇒ Object

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



537
538
539
540
541
# File 'lib/HDLRuby/hruby_low2c.rb', line 537

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

#to_high(level = 0) ⇒ Object

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



195
196
197
198
199
200
201
202
203
204
205
# File 'lib/HDLRuby/hruby_low2high.rb', line 195

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

#to_verilogObject

Converts the system to Verilog code.



1426
1427
1428
1429
1430
1431
1432
# File 'lib/HDLRuby/hruby_verilog.rb', line 1426

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.



642
643
644
645
646
647
648
649
650
651
652
653
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
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 642

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

#unsigned?Boolean

Tells if the type is unsigned.

Returns:

  • (Boolean)


1642
1643
1644
# File 'lib/HDLRuby/hruby_low.rb', line 1642

def unsigned?
    return @base.unsigned?
end

#vector?Boolean

Tells if the type of of vector kind.

Returns:

  • (Boolean)


1556
1557
1558
# File 'lib/HDLRuby/hruby_low.rb', line 1556

def vector?
    return true
end

#widthObject

Gets the bitwidth of the type, nil for undefined.

NOTE: must be redefined for specific types.



1620
1621
1622
1623
1624
# File 'lib/HDLRuby/hruby_low.rb', line 1620

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