Class: HDLRuby::Low::RefName

Inherits:
Ref show all
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_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

Extends the RefName class with functionality for converting booleans in assignments to select operators.

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



1457
1458
1459
1460
1461
1462
1463
# File 'lib/HDLRuby/hruby_verilog.rb', line 1457

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.



326
327
328
329
330
331
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 326

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.



341
342
343
344
345
346
347
348
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 341

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.



448
449
450
451
452
453
454
455
456
457
458
459
460
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 448

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.



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

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+



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

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)


184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 184

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.



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 208

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.



1955
1956
1957
1958
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1955

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.



1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1968

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.



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 235

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.



1949
1950
1951
1952
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1949

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

#set_ref!(ref) ⇒ Object

Sets the base reference.



1938
1939
1940
1941
1942
1943
1944
1945
1946
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1938

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.



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

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



1453
1454
1455
# File 'lib/HDLRuby/hruby_verilog.rb', line 1453

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)



3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
# File 'lib/HDLRuby/hruby_low2c.rb', line 3081

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)



3123
3124
3125
3126
3127
# File 'lib/HDLRuby/hruby_low2c.rb', line 3123

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.



706
707
708
709
710
711
712
713
714
715
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 706

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.



495
496
497
498
499
# File 'lib/HDLRuby/hruby_low2high.rb', line 495

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.



1446
1447
1448
1449
1450
# File 'lib/HDLRuby/hruby_verilog.rb', line 1446

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.



1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1508

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