Class: HDLRuby::Low::RefName

Inherits:
Ref show all
Includes:
ForceName
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_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_namespace.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 included from ForceName

#extend_name!, #force_name!

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

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



6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
# File 'lib/HDLRuby/hruby_low.rb', line 6196

def initialize(type,ref,name)
    # puts "new RefName with name=#{name}"
    if !name or name.empty? then
      raise "Internal error: Creating a RefName without a name."
    end
    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.



6192
6193
6194
# File 'lib/HDLRuby/hruby_low.rb', line 6192

def name
  @name
end

#refObject (readonly)

The accessed reference.



6189
6190
6191
# File 'lib/HDLRuby/hruby_low.rb', line 6189

def ref
  @ref
end

Instance Method Details

#ancestor(my) ⇒ Object



1530
1531
1532
1533
1534
1535
1536
# File 'lib/HDLRuby/hruby_verilog.rb', line 1530

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)



6291
6292
6293
# File 'lib/HDLRuby/hruby_low.rb', line 6291

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.



6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
# File 'lib/HDLRuby/hruby_low.rb', line 6216

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.



6263
6264
6265
6266
6267
6268
# File 'lib/HDLRuby/hruby_low.rb', line 6263

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.



6273
6274
6275
6276
6277
6278
6279
6280
# File 'lib/HDLRuby/hruby_low.rb', line 6273

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)


6235
6236
6237
6238
6239
6240
6241
6242
6243
# File 'lib/HDLRuby/hruby_low.rb', line 6235

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

#fix_scope_refnames!(scopes) ⇒ Object

Fix the references names using scopes given in +scopes + list (they are marked to be deleted).



862
863
864
865
866
867
868
869
870
871
872
873
874
875
# File 'lib/HDLRuby/hruby_low_without_namespace.rb', line 862

def fix_scope_refnames!(scopes)
    return self unless self.ref.is_a?(RefName)
    # puts "fix_scope_refnames! with self=#{self} self.name=#{name} and self.ref=#{self.ref}"
    # Recurse on the ref.
    # self.set_ref!(self.ref.fix_scope_refnames!(scopes))
    # Rename and curt the subref if referening to one of the scopes.
    if scopes.find {|scope| scope.name == self.ref.name } then
        self.ref.extend_name!(self)
        # But need to remove the scope reference.
        self.set_ref!(RefThis.new)
    end
    # puts "Now self=#{self} self.name=#{self.name} self.ref=#{self.ref}"
    return self
end

#flattenObject

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



288
289
290
291
292
# File 'lib/HDLRuby/hruby_low_without_subsignals.rb', line 288

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+



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/HDLRuby/hruby_low_without_subsignals.rb', line 245

def flatten_to(sig,subrefs)
    # puts "flatten_to with sig=#{sig}"
    # Shall we decompose 2d vectors, and is the current signal
    # for one of them?
    if SystemT.decompose_vec2d? and sig.type.is_a?(TypeVector) and
            sig.type.base.is_a?(TypeVector) then
        # Is the reference used other than for a memory access?
        unless self.parent.is_a?(RefIndex) then
            # Yes, do the decomposition.
            # Selects the direction.
            rng = sig.type.range
            if rng.first > rng.last then
                itr = (rng.last..rng.first).each
            else
                itr = rng.reverse_each
            end
            # Iterate on each element.
            itr.each do |i|
                # Create a reference fo the sub.
                subref = RefIndex.new(sig.type.base,self.clone,
                                          Value.new(TypeUnsigned.new(:""),i))
                # Add it.
                subrefs << subref
            end
        end
    else
        # 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)
            # Recurse 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
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.



6229
6230
6231
6232
# File 'lib/HDLRuby/hruby_low.rb', line 6229

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.



6246
6247
6248
# File 'lib/HDLRuby/hruby_low.rb', line 6246

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.



6253
6254
6255
6256
6257
6258
6259
6260
# File 'lib/HDLRuby/hruby_low.rb', line 6253

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
257
# 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}"
        return obj if obj.name == self.name
        # 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 "Going get_by_name with name=#{self.name}"
                found = parent.get_by_name(self.name)
                # puts "found=#{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.



295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/HDLRuby/hruby_low_without_subsignals.rb', line 295

def signal2subs!
    # puts "signal2subs! for RefName: #{self.name}"
    return self if self.type == void # Not a singal anyway.
    # 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).



1526
1527
1528
# File 'lib/HDLRuby/hruby_verilog.rb', line 1526

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.



1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
# File 'lib/HDLRuby/hruby_verilog.rb', line 1512

def to_verilog
    if (self.ref.is_a?(RefThis)) then
        # End reference.
        vname = name_to_verilog(self.name)
    else
        # Not end reference, recurse.
        # vname = name_to_verilog(self.name) + "." + self.ref.to_verilog 
        vname = self.ref.to_verilog + "." + name_to_verilog(self.name)
    end
    # 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

#to_viz_namesObject

Get the port names for visualization from the expression.



4999
5000
5001
5002
5003
# File 'lib/HDLRuby/hruby_viz.rb', line 4999

def to_viz_names
  res = self.ref.to_viz_names[0]
  res += "." unless res.empty?
  return [ res + self.name.to_s ]
end

#to_viz_node(parent) ⇒ Object

Converts the index reference to a Viz flow node under +parent+.



5006
5007
5008
5009
5010
5011
5012
# File 'lib/HDLRuby/hruby_viz.rb', line 5006

def to_viz_node(parent)
  # Create the viz node.
  node = HDLRuby::Viz::Node.new(:".",parent,self.name.to_s)
  # Generate the base if any.
  self.ref.to_viz_node(node)
  return node
end

#use_name?(*names) ⇒ Boolean

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

Returns:

  • (Boolean)


6283
6284
6285
6286
6287
6288
# File 'lib/HDLRuby/hruby_low.rb', line 6283

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