Class: HDLRuby::Low::RefIndex

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

Overview

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

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.



299
300
301
302
303
304
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 299

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.



307
308
309
310
311
312
313
314
315
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 307

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.



404
405
406
407
408
409
410
411
412
413
414
415
416
417
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 404

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)


146
147
148
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 146

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.



1790
1791
1792
1793
1794
1795
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1790

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.



1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1805

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.



153
154
155
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 153

def resolve
    return self.ref.resolve
end

#set_index!(ref) ⇒ Object

Sets the index.



1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1778

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.



1767
1768
1769
1770
1771
1772
1773
1774
1775
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1767

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.



2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
# File 'lib/HDLRuby/hruby_low2c.rb', line 2900

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)



2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
# File 'lib/HDLRuby/hruby_low2c.rb', line 2941

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.



685
686
687
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 685

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.



473
474
475
476
477
# File 'lib/HDLRuby/hruby_low2high.rb', line 473

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.



1470
1471
1472
# File 'lib/HDLRuby/hruby_verilog.rb', line 1470

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.



1458
1459
1460
1461
1462
1463
1464
1465
1466
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1458

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