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



5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
# File 'lib/HDLRuby/hruby_low.rb', line 5607

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.



5603
5604
5605
# File 'lib/HDLRuby/hruby_low.rb', line 5603

def index
  @index
end

#refObject (readonly)

The accessed reference.



5600
5601
5602
# File 'lib/HDLRuby/hruby_low.rb', line 5600

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)



5704
5705
5706
# File 'lib/HDLRuby/hruby_low.rb', line 5704

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.



5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
# File 'lib/HDLRuby/hruby_low.rb', line 5636

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.



5676
5677
5678
5679
5680
5681
5682
# File 'lib/HDLRuby/hruby_low.rb', line 5676

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.



5687
5688
5689
5690
5691
5692
5693
5694
5695
# File 'lib/HDLRuby/hruby_low.rb', line 5687

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)


5652
5653
5654
5655
5656
5657
5658
5659
5660
# File 'lib/HDLRuby/hruby_low.rb', line 5652

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.



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

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)


132
133
134
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 132

def from_systemI?
    return self.ref.from_systemI?
end

#hashObject

Hash function.



5663
5664
5665
# File 'lib/HDLRuby/hruby_low.rb', line 5663

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

#immutable?Boolean

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

Returns:

  • (Boolean)


5628
5629
5630
5631
# File 'lib/HDLRuby/hruby_low.rb', line 5628

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

#map_nodes!(&ruby_block) ⇒ Object

Maps on the children.



1771
1772
1773
1774
1775
1776
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1771

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.



5670
5671
5672
5673
# File 'lib/HDLRuby/hruby_low.rb', line 5670

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.



1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1784

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.



139
140
141
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 139

def resolve
    return self.ref.resolve
end

#set_index!(ref) ⇒ Object

Sets the index.



1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1759

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.



1748
1749
1750
1751
1752
1753
1754
1755
1756
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1748

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.



2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
# File 'lib/HDLRuby/hruby_low2c.rb', line 2868

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)



2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
# File 'lib/HDLRuby/hruby_low2c.rb', line 2909

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.



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

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)


5698
5699
5700
5701
# File 'lib/HDLRuby/hruby_low.rb', line 5698

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