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_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

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

Methods included from Low2Symbol

#to_sym

Methods included from Hparent

#scope

Constructor Details

#initialize(type, ref, index) ⇒ RefIndex

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



4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
# File 'lib/HDLRuby/hruby_low.rb', line 4631

def initialize(type,ref,index)
    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 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.



4627
4628
4629
# File 'lib/HDLRuby/hruby_low.rb', line 4627

def index
  @index
end

#refObject (readonly)

The accessed reference.



4624
4625
4626
# File 'lib/HDLRuby/hruby_low.rb', line 4624

def ref
  @ref
end

Instance Method Details

#boolean_in_assign2selectObject

Converts booleans in assignments to select operators.



273
274
275
276
277
278
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 273

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

#cloneObject

Clones the indexed references (deeply)



4703
4704
4705
# File 'lib/HDLRuby/hruby_low.rb', line 4703

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

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

Iterates over the reference children if any.



4675
4676
4677
4678
4679
4680
4681
# File 'lib/HDLRuby/hruby_low.rb', line 4675

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.



4686
4687
4688
4689
4690
4691
4692
4693
4694
# File 'lib/HDLRuby/hruby_low.rb', line 4686

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)


4651
4652
4653
4654
4655
4656
4657
4658
4659
# File 'lib/HDLRuby/hruby_low.rb', line 4651

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.



370
371
372
373
374
375
376
377
378
379
380
381
382
383
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 370

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)


93
94
95
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 93

def from_systemI?
    return self.ref.from_systemI?
end

#hashObject

Hash function.



4662
4663
4664
# File 'lib/HDLRuby/hruby_low.rb', line 4662

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

#map_nodes!(&ruby_block) ⇒ Object

Maps on the children.



1689
1690
1691
1692
1693
1694
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1689

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.



4669
4670
4671
4672
# File 'lib/HDLRuby/hruby_low.rb', line 4669

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.



1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1702

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

#set_index!(ref) ⇒ Object

Sets the index.



1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1677

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.



1666
1667
1668
1669
1670
1671
1672
1673
1674
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1666

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(level = 0, left = false) ⇒ Object

Generates the C text of the equivalent HDLRuby::High code. +level+ is thehierachical level of the object and +left+ tells if it is a left value or not.



1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
# File 'lib/HDLRuby/hruby_low2c.rb', line 1879

def to_c(level = 0, left = false)
    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"
    # Compute the index.
    res << (" " * ((level+1)*3))
    # res << "idx = read64(#{self.index.to_c(level+2)});\n"
    res << "idx = value2integer(#{self.index.to_c(level+2)});\n"
    # Make the access.
    res << (" " * ((level+1)*3))
    # res << "dst = read_range(ref,idx,idx,#{self.ref.type.base.to_c(level)},dst);\n"
    res << "dst = read_range(ref,idx,idx,#{self.type.to_c(level)},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; })"
end

#to_c_signal(level = 0) ⇒ Object

Generates the C text for reference as left value to a signal. +level+ is the hierarchical level of the object.



1910
1911
1912
1913
# File 'lib/HDLRuby/hruby_low2c.rb', line 1910

def to_c_signal(level = 0)
    return "make_ref_rangeS(#{self.ref.to_c_signal(level)}," +
        "value2integer(#{self.index.to_c(level)}),value2integer(#{self.index.to_c(level)}))"
end

#to_high(level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.



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

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

#to_verilogObject

Converts the system to Verilog code.



1341
1342
1343
# File 'lib/HDLRuby/hruby_verilog.rb', line 1341

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.



1420
1421
1422
1423
1424
1425
1426
1427
1428
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1420

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)


4697
4698
4699
4700
# File 'lib/HDLRuby/hruby_low.rb', line 4697

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