Class: HDLRuby::Low::RefIndex

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_casts_without_expression.rb

Overview

Describes a index reference.

Direct Known Subclasses

High::RefIndex

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!, #leftvalue?, #replace_names!, #rightvalue?, #set_type!, #signal2subs!, #statement, #to_c_expr

Methods included from Low2Symbol

#to_sym

Methods included from Hparent

#hierarchy, #no_parent!, #scope

Constructor Details

#initialize(type, ref, index) ⇒ RefIndex

Create a new index reference with +type+ accessing +ref+ at +index+. def initialize(ref,index)



5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
# File 'lib/HDLRuby/hruby_low.rb', line 5778

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

Instance Attribute Details

#indexObject (readonly)

The access index.



5774
5775
5776
# File 'lib/HDLRuby/hruby_low.rb', line 5774

def index
  @index
end

#refObject (readonly)

The accessed reference.



5771
5772
5773
# File 'lib/HDLRuby/hruby_low.rb', line 5771

def ref
  @ref
end

Instance Method Details

#boolean_in_assign2selectObject

Converts booleans in assignments to select operators.



310
311
312
313
314
315
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 310

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

#casts_without_expression!Object

Extracts the expressions from the casts.



316
317
318
319
320
321
322
323
324
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 316

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

#cloneObject

Clones the indexed references (deeply)



5875
5876
5877
# File 'lib/HDLRuby/hruby_low.rb', line 5875

def clone
    return RefIndex.new(@type, @ref.clone, @index.clone)
end

#each_deep(&ruby_block) ⇒ Object

Iterates over each object deeply.

Returns an enumerator if no ruby block is given.



5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
# File 'lib/HDLRuby/hruby_low.rb', line 5807

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)
    # Then apply on the index if possible.
    if self.index.respond_to?(:each_deep) then
        self.index.each_deep(&ruby_block)
    end
end

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

Iterates over the reference children if any.



5847
5848
5849
5850
5851
5852
5853
# File 'lib/HDLRuby/hruby_low.rb', line 5847

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 index and the ref.
    ruby_block.call(@index)
    ruby_block.call(@ref)
end

#each_node_deep(&ruby_block) ⇒ Object

Iterates over the nodes deeply if any.



5858
5859
5860
5861
5862
5863
5864
5865
5866
# File 'lib/HDLRuby/hruby_low.rb', line 5858

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 children.
    @index.each_node_deep(&ruby_block)
    @ref.each_node_deep(&ruby_block)
end

#eql?(obj) ⇒ Boolean

Comparison for hash: structural comparison.

Returns:

  • (Boolean)


5823
5824
5825
5826
5827
5828
5829
5830
5831
# File 'lib/HDLRuby/hruby_low.rb', line 5823

def eql?(obj)
    # General comparison.
    return false unless super(obj)
    # Specific comparison.
    return false unless obj.is_a?(RefIndex)
    return false unless @index.eql?(obj.index)
    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.



432
433
434
435
436
437
438
439
440
441
442
443
444
445
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 432

def explicit_types(type = nil)
    # Is there a type to match ?
    if type then
        # Regenerate the reference and cast it
        return Cast.new(type,
                RefIndex.new(self.type,self.ref.explicit_types,
                            self.index.explicit_types))
    else
        # No, recurse with the type of the current index ref.
        return RefIndex.new(self.type,
                            self.ref.explicit_types,
                            self.index.explicit_types)
    end
end

#from_systemI?Boolean

Tells if it is a reference to a systemI signal.

Returns:

  • (Boolean)


143
144
145
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 143

def from_systemI?
    return self.ref.from_systemI?
end

#hashObject

Hash function.



5834
5835
5836
# File 'lib/HDLRuby/hruby_low.rb', line 5834

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

#immutable?Boolean

Tells if the expression is immutable (cannot be written.)

Returns:

  • (Boolean)


5799
5800
5801
5802
# File 'lib/HDLRuby/hruby_low.rb', line 5799

def immutable?
    # Immutable if the ref is immutable.
    return self.ref.immutable?
end

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

Maps on the children.



1731
1732
1733
1734
1735
1736
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1731

def map_nodes!(&ruby_block)
    @index = ruby_block.call(@index)
    @index.parent = self unless @index.parent
    @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.



5841
5842
5843
5844
# File 'lib/HDLRuby/hruby_low.rb', line 5841

def path_each(&ruby_block)
    # Recurse on the base reference.
    return ref.path_each(&ruby_block)
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.



1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1746

def replace_expressions!(node2rep)
    # First recurse on the ref.
    res = self.ref.replace_expressions!(node2rep)
    # And and the index.
    res = self.index.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
    # Is there a replacement to on the index?
    rep = node2rep[self.index]
    if rep then
        # Yes, do it.
        rep = rep.clone
        node = self.index
        # node.set_parent!(nil)
        self.set_index!(rep)
        # And register the replacement.
        res[node] = rep
    end
    return res
end

#resolveObject

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



150
151
152
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 150

def resolve
    return self.ref.resolve
end

#set_index!(ref) ⇒ Object

Sets the index.



1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1719

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

#set_ref!(ref) ⇒ Object

Sets the base reference.



1708
1709
1710
1711
1712
1713
1714
1715
1716
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1708

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

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

Generates the C text of the equivalent HDLRuby code.

+level+ is thehierachical level of the object and

+left+ tells if it is a left value or not.

def to_c(level = 0, left = false)

def to_c(res,level = 0, left = false) # res = "( res << "({\n" # And allocates a new value for dst. res << (" " * ((level+1)*3)) res << "Value ref,dst = get_value();\n" res << (" " * ((level+1)*3)) res << "unsigned long long idx;\n" # Save the state of the value pool. res << (" " * ((level+1)*3)) res << "unsigned int pool_state = get_value_pos();\n" # Compute the reference. res << (" " * ((level+1)*3)) # res << "ref = #{self.ref.to_c(level+2);\n" res << "ref = " self.ref.to_c(res,level+2) res << ";\n" # Compute the index. res << (" " * ((level+1)*3)) # res << "idx = value2integer(#HDLRuby::Low::RefIndex.selfself.indexself.index.to_c(level+2));\n" res << "idx = value2integer(" self.index.to_c(res,level+2) res << ");\n" # Make the access. res << (" " * ((level+1)*3)) # puts "self.type.width=#HDLRuby::Low::RefIndex.selfself.typeself.type.width" # res << "dst = read_range(ref,idx,idx,#HDLRuby::Low::RefIndex.selfself.typeself.type.to_c(level),dst);\n" res << "dst = read_range(ref,idx,idx," # res << self.type.to_c(level) self.type.to_c(res,level) res << ",dst);\n" # Restore the state of the value pool. res << (" " * ((level+1)*3)) res << "set_value_pos(pool_state);\n" # Close the computation. res << (" " * (level*3)) res << "dst; })" return res end Generates the C text of the equivalent HDLRuby code. +level+ is thehierachical level of the object and +left+ tells if it is a left value or not.



2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
# File 'lib/HDLRuby/hruby_low2c.rb', line 2914

def to_c(res,level = 0, left = false)
    # Save the value pool state.
    res << (" " * (level*3)) << "PV;\n"
    # Compute the reference.
    self.ref.to_c(res,level)
    # Compute the index.
    self.index.to_c(res,level)
    res << (" " * (level*3))
    # Make the access.
    res << (" " * (level*3))
    if (left) then
        res << "swriteI("
    else
        res << "sreadI("
    end
    self.type.to_c(res,level)
    res << ");\n"
    # Restore the value pool state.
    res << (" " * (level*3)) << "RV;\n"
    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)

def to_c_signal(res,level = 0) # puts "to_c_signal for RefIndex" res << "make_ref_rangeS(" self.ref.to_c_signal(res,level) res << "," self.type.to_c(res,level) res << ",value2integer(" self.index.to_c(res,level) res << "),value2integer(" self.index.to_c(res,level) res << "))" return res end 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)



2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
# File 'lib/HDLRuby/hruby_low2c.rb', line 2955

def to_c_signal(res,level = 0)
    # puts "to_c_signal for RefIndex"
    res << "make_ref_rangeS("
    self.ref.to_c_signal(res,level)
    res << ","
    self.type.to_c(res,level)
    res << ",value2integer(({\n"
    self.index.to_c(res,level)
    res << " " * ((level+1)*3)
    res << "pop();})"
    res << "),value2integer(({\n"
    self.index.to_c(res,level)
    res << " " * ((level+1)*3)
    res << "pop();})"
    res << "))"
    return res
end

#to_hdr(level = 0) ⇒ Object

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



707
708
709
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 707

def to_hdr(level = 0)
    return self.ref.to_hdr(level) + "[#{self.index.to_hdr(level)}]"
end

#to_highObject

Creates a new high index reference.



511
512
513
514
515
# File 'lib/HDLRuby/hruby_low2high.rb', line 511

def to_high
    return HDLRuby::High::RefIndex.new(self.type.to_high,
                                       self.ref.to_high,
                                       self.index.to_high)
end

#to_verilogObject

Converts the system to Verilog code.



1481
1482
1483
# File 'lib/HDLRuby/hruby_verilog.rb', line 1481

def to_verilog
    return "#{self.ref.to_verilog}[#{self.index.to_verilog}]"
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.



1489
1490
1491
1492
1493
1494
1495
1496
1497
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1489

def to_vhdl(level = 0, std_logic = false)
    if self.index.is_a?(Value) then
        return self.ref.to_vhdl(level,std_logic) + 
            "(#{self.index.to_vhdl(level)})"
    else
        return self.ref.to_vhdl(level,std_logic) +
            "(to_integer(unsigned(#{self.index.to_vhdl(level)})))"
    end
end

#use_name?(*names) ⇒ Boolean

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

Returns:

  • (Boolean)


5869
5870
5871
5872
# File 'lib/HDLRuby/hruby_low.rb', line 5869

def use_name?(*names)
    # Recurse on the index and the reference.
    return @index.use_name?(names) || @ref.use_name?(*names)
end