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

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?, #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, #scope

Constructor Details

#initialize(name, direction, content) ⇒ TypeStruct

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



1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
# File 'lib/HDLRuby/hruby_low.rb', line 1991

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.



374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 374

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.



2053
2054
2055
2056
2057
2058
# File 'lib/HDLRuby/hruby_low.rb', line 2053

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.



2073
2074
2075
2076
2077
2078
# File 'lib/HDLRuby/hruby_low.rb', line 2073

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.



2063
2064
2065
2066
2067
2068
# File 'lib/HDLRuby/hruby_low.rb', line 2063

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 Also known as: each_deep

Iterates over the types deeply if any.



2081
2082
2083
2084
2085
2086
2087
2088
# File 'lib/HDLRuby/hruby_low.rb', line 2081

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)


2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
# File 'lib/HDLRuby/hruby_low.rb', line 2012

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)


2137
2138
2139
2140
2141
2142
# File 'lib/HDLRuby/hruby_low.rb', line 2137

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.



2041
2042
2043
# File 'lib/HDLRuby/hruby_low.rb', line 2041

def get_all_types
    return @types.values
end

#get_type(name) ⇒ Object

Gets a sub type by +name+.



2046
2047
2048
# File 'lib/HDLRuby/hruby_low.rb', line 2046

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

#hashObject

Hash function.



2026
2027
2028
# File 'lib/HDLRuby/hruby_low.rb', line 2026

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)


2031
2032
2033
# File 'lib/HDLRuby/hruby_low.rb', line 2031

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)



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

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


2036
2037
2038
# File 'lib/HDLRuby/hruby_low.rb', line 2036

def types?
    return true
end

#widthObject

Gets the bitwidth of the type, nil for undefined.

NOTE: must be redefined for specific types.



2095
2096
2097
# File 'lib/HDLRuby/hruby_low.rb', line 2095

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