Class: HDLRuby::Low::RefName

Inherits:
Ref show all
Defined in:
lib/HDLRuby/hruby_low.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_resolve.rb,
lib/HDLRuby/hruby_low_skeleton.rb,
lib/HDLRuby/hruby_low_fix_types.rb,
lib/HDLRuby/hruby_low_bool2select.rb,
lib/HDLRuby/hruby_low_without_subsignals.rb,
lib/HDLRuby/hruby_low_casts_without_expression.rb

Overview

Describes a name reference.

Direct Known Subclasses

High::RefName

Constant Summary

Constants included from Low2Symbol

Low2Symbol::Low2SymbolPrefix, Low2Symbol::Low2SymbolTable, Low2Symbol::Symbol2LowTable

Instance Attribute Summary collapse

Attributes inherited from Expression

#type

Attributes included from Hparent

#parent

Instance Method Summary collapse

Methods inherited from Expression

#boolean?, #break_types!, #each_ref_deep, #extract_selects_to!, #immutable?, #leftvalue?, #replace_names!, #rightvalue?, #set_type!, #statement, #to_c_expr

Methods included from Low2Symbol

#to_sym

Methods included from Hparent

#hierarchy, #no_parent!, #scope

Constructor Details

#initialize(type, ref, name) ⇒ RefName

Create a new named reference with +type+ accessing +ref+ with +name+. def initialize(ref,name)



6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
# File 'lib/HDLRuby/hruby_low.rb', line 6022

def initialize(type,ref,name)
    super(type)
    # Check and set the accessed reference.
    unless ref.is_a?(Ref) then
        raise AnyError, "Invalid class for a reference: #{ref.class}."
    end
    @ref = ref
    # And set its parent.
    ref.parent = self
    # Check and set the symbol.
    @name = name.to_sym
end

Instance Attribute Details

#nameObject (readonly)

The access name.



6018
6019
6020
# File 'lib/HDLRuby/hruby_low.rb', line 6018

def name
  @name
end

#refObject (readonly)

The accessed reference.



6015
6016
6017
# File 'lib/HDLRuby/hruby_low.rb', line 6015

def ref
  @ref
end

Instance Method Details

#ancestor(my) ⇒ Object



1467
1468
1469
1470
1471
1472
1473
# File 'lib/HDLRuby/hruby_verilog.rb', line 1467

def ancestor(my)
    if my.parent.parent.respond_to? (:mode) then
        return ancestor(my.parent)
    else
        return "#{my.parent.mode.to_s}#{my.mode.to_s}"
    end
end

#boolean_in_assign2selectObject

Converts booleans in assignments to select operators.



339
340
341
342
343
344
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 339

def boolean_in_assign2select
    # Recurse on the sub references.
    return RefName.new(self.type,
                       self.ref.boolean_in_assign2select,
                       self.name)
end

#casts_without_expression!Object

Extracts the expressions from the casts.



352
353
354
355
356
357
358
359
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 352

def casts_without_expression!
    # Recurse on the sub references.
    # return RefName.new(self.type,
    #                    self.ref.casts_without_expression,
    #                    self.name)
    self.set_ref!(self.ref.casts_without_expression!)
    return self
end

#cloneObject

Clones the name references (deeply)



6113
6114
6115
# File 'lib/HDLRuby/hruby_low.rb', line 6113

def clone
    return RefName.new(@type, @ref.clone, @name)
end

#each_deep(&ruby_block) ⇒ Object

Iterates over each object deeply.

Returns an enumerator if no ruby block is given.



6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
# File 'lib/HDLRuby/hruby_low.rb', line 6038

def each_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_deep) unless ruby_block
    # A ruby block? First apply it to current.
    ruby_block.call(self)
    # Then apply on the type.
    self.type.each_deep(&ruby_block)
    # Then apply on the reference.
    self.ref.each_deep(&ruby_block)
end

#each_node(&ruby_block) ⇒ Object Also known as: each_expression

Iterates over the reference children if any.



6085
6086
6087
6088
6089
6090
# File 'lib/HDLRuby/hruby_low.rb', line 6085

def each_node(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_node) unless ruby_block
    # A ruby block? Apply it on the child.
    ruby_block.call(@ref)
end

#each_node_deep(&ruby_block) ⇒ Object

Iterates over the nodes deeply if any.



6095
6096
6097
6098
6099
6100
6101
6102
# File 'lib/HDLRuby/hruby_low.rb', line 6095

def each_node_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_node_deep) unless ruby_block
    # A ruby block? First apply it to current.
    ruby_block.call(self)
    # And recurse on the child.
    @ref.each_node_deep(&ruby_block)
end

#eql?(obj) ⇒ Boolean

Comparison for hash: structural comparison.

Returns:

  • (Boolean)


6057
6058
6059
6060
6061
6062
6063
6064
6065
# File 'lib/HDLRuby/hruby_low.rb', line 6057

def eql?(obj)
    # General comparison.
    return false unless super(obj)
    # Specific comparison.
    return false unless obj.is_a?(RefName)
    return false unless @name.eql?(obj.name)
    return false unless @ref.eql?(obj.ref)
    return true
end

#explicit_types(type = nil) ⇒ Object

Explicit the types conversions in the index ref where +type+ is the expected type of the condition if any.



478
479
480
481
482
483
484
485
486
487
488
489
490
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 478

def explicit_types(type = nil)
    # Is there a type to match, if not use current one.
    type = self.type unless type
    # Cast if required and return the new reference.
    if self.type.eql?(type) then
        # No need to cast.
        return RefName.new(type,self.ref.explicit_types,self.name)
    else
        # Need a cast.
        return Cast.new(type,
           RefName.new(self.type,self.ref.explicit_types,self.name))
    end
end

#flattenObject

Flatten the current ref to a list of references. If the reference is not heirachical, returns an empty list.



249
250
251
252
253
# File 'lib/HDLRuby/hruby_low_without_subsignals.rb', line 249

def flatten
    subrefs = []
    self.flatten_to(self.resolve,subrefs)
    return subrefs
end

#flatten_to(sig, subrefs) ⇒ Object

Flatten a reference to a list of reference to leaf signals from signal +sig+ and add to result to +subrefs+



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/HDLRuby/hruby_low_without_subsignals.rb', line 231

def flatten_to(sig,subrefs)
    # puts "flatten_to with sig name=#{sig.name}"
    # Work on the sub signals if any.
    sig.each_signal do |sub|
        # Create a reference for the sub.
        subref = RefName.new(sub.type,self.clone,sub.name)
        # Recruse on it.
        subref.flatten_to(sub,subrefs)
        # Was it a leaf?
        unless sub.each_signal.any? then
            # Yes, add its new ref to the list of subs.
            subrefs << subref
        end
    end
end

#from_systemI?Boolean

Tells if it is a reference to a systemI signal.

Returns:

  • (Boolean)


179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 179

def from_systemI?
    # Look for the owner from the name hierarchy.
    if self.ref.is_a?(RefName) then
        # Look in the parent hierachy for the sub reference name.
        parent = self.parent
        # puts "self.ref.name=#{self.ref.name}"
        while parent
            # puts "parent=#{parent}"
            if parent.respond_to?(:get_by_name) then
                found = parent.get_by_name(self.ref.name)
                # puts "found is a :#{found.class}"
                return found.is_a?(SystemI) if found
            end
            parent = parent.parent
        end
        # Not found, look further in the reference hierarchy.
        return self.ref.from_systemI?
    end
    # Not from a systemI.
    # puts "Not from systemI for #{self.name}"
    return false
end

#full_nameObject

Get the full name of the reference, i.e. including the sub ref names if any.



6051
6052
6053
6054
# File 'lib/HDLRuby/hruby_low.rb', line 6051

def full_name
    name = self.ref.respond_to?(:full_name) ? self.ref.full_name : :""
    return :"#{name}::#{self.name}"
end

#get_systemIObject

Gets the systemI the reference comes from if any.



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 203

def get_systemI
    # Look for the owner from the name hierarchy.
    if self.ref.is_a?(RefName) then
        # Look in the parent hierachy for the sub reference name.
        parent = self.parent
        # puts "self.ref.name=#{self.ref.name}"
        while parent
            # puts "parent=#{parent}"
            if parent.respond_to?(:get_by_name) then
                found = parent.get_by_name(self.ref.name)
                # puts "found is a :#{found.class}"
                return found if found.is_a?(SystemI)
            end
            parent = parent.parent
        end
        # Not found, look further in the reference hierarchy.
        return self.ref.get_systemI
    end
    # Not from a systemI.
    # puts "Not from systemI for #{self.name}"
    return nil
end

#hashObject

Hash function.



6068
6069
6070
# File 'lib/HDLRuby/hruby_low.rb', line 6068

def hash
    return [super,@name,@ref].hash
end

#map_nodes!(&ruby_block) ⇒ Object Also known as: map_expressions!

Maps on the children.



1895
1896
1897
1898
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1895

def map_nodes!(&ruby_block)
    @ref = ruby_block.call(@ref)
    @ref.parent = self unless @ref.parent
end

#path_each(&ruby_block) ⇒ Object

Iterates over the names of the path indicated by the reference.

Returns an enumerator if no ruby block is given.



6075
6076
6077
6078
6079
6080
6081
6082
# File 'lib/HDLRuby/hruby_low.rb', line 6075

def path_each(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:path_each) unless ruby_block
    # Recurse on the base reference.
    ref.path_each(&ruby_block)
    # Applies the block on the current name.
    ruby_block.call(@name)
end

#replace_expressions!(node2rep) ⇒ Object

Replaces sub expressions using +node2rep+ table indicating the node to replace and the corresponding replacement. Returns the actually replaced nodes and their corresponding replacement.

NOTE: the replacement is duplicated.



1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1908

def replace_expressions!(node2rep)
    # First recurse on the ref.
    res = self.ref.replace_expressions!(node2rep)
    
    # Is there a replacement to on the ref?
    rep = node2rep[self.ref]
    if rep then
        # Yes, do it.
        rep = rep.clone
        node = self.ref
        # node.set_parent!(nil)
        self.set_ref!(rep)
        # And register the replacement.
        res[node] = rep
    end
    return res
end

#resolveObject

Resolves the name of the reference and return the corresponding object. NOTE: return nil if could not resolve.



230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 230

def resolve
    # puts "Resolve with #{self} and name=#{self.name} and ref=#{self.ref.class}"
    # First resolve the sub reference if possible.
    if self.ref.is_a?(RefName) then
        obj = self.ref.resolve
        # puts "obj=#{obj}"
        # Look into the object for the name.
        return obj.get_by_name(self.name)
    else
        # Look in the parent hierachy for the name.
        parent = self.parent
        # puts "parent=#{parent}"
        while parent
            # puts "parent=#{parent}"
            if parent.respond_to?(:get_by_name) then
                # puts "get_by_name"
                found = parent.get_by_name(self.name)
                # puts "found" if found
                return found if found
            end
            parent = parent.parent
        end
        # Not found.
        puts "Not found!"
        return nil
    end
end

#set_name!(name) ⇒ Object

Sets the name.



1889
1890
1891
1892
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1889

def set_name!(name)
    # Check and set the symbol.
    @name = name.to_sym
end

#set_ref!(ref) ⇒ Object

Sets the base reference.



1878
1879
1880
1881
1882
1883
1884
1885
1886
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1878

def set_ref!(ref)
    # Check and set the accessed reference.
    unless ref.is_a?(Ref) then
        raise AnyError, "Invalid class for a reference: #{ref.class}."
    end
    @ref = ref
    # And set its parent.
    ref.parent = self
end

#signal2subs!Object

Decompose the hierarchical signals in the statements.



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/HDLRuby/hruby_low_without_subsignals.rb', line 256

def signal2subs!
    # puts "signal2subs! for RefName: #{self.name}"
    # Decompose it to a list of reference to each leaf sub signal.
    subrefs = []
    self.flatten_to(self.resolve,subrefs)
    # puts "subrefs=#{subrefs.map{|subref| subref.name}}"
    # Has it sub signals?
    if (subrefs.any?) then
        # Yes, convert it to a Concat.
        if self.leftvalue? then
            return RefConcat.new(self.type,subrefs)
        else
            return Concat.new(self.type,subrefs)
        end
    else
        # Nothing to do.
        return self
    end
end

#to_another_verilogObject

Used for instantiation (emergency procedure).



1463
1464
1465
# File 'lib/HDLRuby/hruby_verilog.rb', line 1463

def to_another_verilog
    return "_#{self.name.to_s}"
end

#to_c(res, level = 0, left = false) ⇒ Object

Generates the C text of the equivalent HDLRuby code. +level+ is the hierachical level of the object and +left+ tells if it is a left value or not. def to_c(level = 0, left = false)



3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
# File 'lib/HDLRuby/hruby_low2c.rb', line 3095

def to_c(res,level = 0, left = false)
    # puts "RefName to_c for #{self.name}"
    res << (" " * (level*3))
    res << "push("
    self.resolve.to_c_signal(res,level+1)
    res << "->" << (left ? "f_value" : "c_value")
    res << ");\n"
    return res
    # sig = self.resolve
    # if sig.each_signal.any? then
    #     # Save the value pool state.
    #     res << (" " * (level*3)) << "PV;\n"
    #     # There are sub signals, get and concat their values.
    #     subs = sig.each_signal.to_a
    #     subs.each do |sub|
    #         res << (" " * (level*3))
    #         res << "push("
    #         sub.to_c_signal(res,level+1)
    #         res << "->" << (left ? "f_value" : "c_value")
    #         res << ");\n"
    #     end
    #     # Compute the resulting concatenation.
    #     res << (" " * ((level+1)*3))
    #     res << "sconcat(#{subs.size},"
    #     res << (sig.type.direction == :little ? "1" : "0")
    #     res << ");\n"
    #     # Restore the value pool state.
    #     res << (" " * (level*3)) << "RV;\n"
    # else
    #     # There is no sub signals, get the signal value.
    #     res << (" " * (level*3))
    #     res << "push("
    #     sig.to_c_signal(res,level+1)
    #     res << "->" << (left ? "f_value" : "c_value")
    #     res << ");\n"
    # end
    # return res
end

#to_c_signal(res, level = 0) ⇒ Object

Generates the C text for reference as left value to a signal. +level+ is the hierarchical level of the object. def to_c_signal(level = 0)



3137
3138
3139
3140
3141
# File 'lib/HDLRuby/hruby_low2c.rb', line 3137

def to_c_signal(res,level = 0)
    # puts "to_c_signal with self=#{self.name}"
    self.resolve.to_c_signal(res,level+1)
    return res
end

#to_hdr(level = 0) ⇒ Object

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



730
731
732
733
734
735
736
737
738
739
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 730

def to_hdr(level = 0)
    # The resulting string.
    res = ""
    # Generates the sub reference if any.
    res << self.ref.to_hdr(level) << "." unless self.ref.is_a?(RefThis)
    # Generates the current reference.
    res << Low2HDR.hdr_use_name(self.name)
    # Returns the resulting string.
    return res
end

#to_highObject

Creates a new high range reference.



535
536
537
538
539
# File 'lib/HDLRuby/hruby_low2high.rb', line 535

def to_high
    return HDLRuby::High::RefName.new(self.type.to_high,
                                      self.ref.to_high,
                                      self.name)
end

#to_verilogObject

Converts the system to Verilog code using +renamer+ for producing Verilog-compatible names.



1456
1457
1458
1459
1460
# File 'lib/HDLRuby/hruby_verilog.rb', line 1456

def to_verilog
    vname = name_to_verilog(self.name)
    # self.properties[:verilog_name] = vname
    return "#{vname}"
end

#to_vhdl(level = 0, std_logic = false) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object. +std_logic+ tells if std_logic computation is to be done.



1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1541

def to_vhdl(level = 0, std_logic = false)
    # The resulting string.
    res = ""
    # Generate the sub refs if any (case of struct).
    unless self.ref.is_a?(RefThis) then
        res << self.ref.to_vhdl(level) << "."
    end
    # Generates the current reference.
    res << Low2VHDL.vhdl_name(self.name)
    res << "(0)" if std_logic # Force to std_logic if required
    # Returns the resulting string.
    return res
end

#use_name?(*names) ⇒ Boolean

Tell if the expression includes a signal whose name is one of +names+.

Returns:

  • (Boolean)


6105
6106
6107
6108
6109
6110
# File 'lib/HDLRuby/hruby_low.rb', line 6105

def use_name?(*names)
    # Is the named used here?
    return true if names.include?(@name)
    # No, recurse the reference.
    return @ref.use_name?(*names)
end