Class: HDLRuby::Low::RefIndex

Inherits:
Ref show all
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_casts_without_expression.rb
more...

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!, #fix_scope_refnames!, #leftvalue?, #replace_names!, #rightvalue?, #set_type!, #signal2subs!, #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, index) ⇒ RefIndex

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

[View source]

5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
# File 'lib/HDLRuby/hruby_low.rb', line 5974

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.


5970
5971
5972
# File 'lib/HDLRuby/hruby_low.rb', line 5970

def index
  @index
end

#refObject (readonly)

The accessed reference.


5967
5968
5969
# File 'lib/HDLRuby/hruby_low.rb', line 5967

def ref
  @ref
end

Instance Method Details

#boolean_in_assign2selectObject

Converts booleans in assignments to select operators.

[View source]

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.

[View source]

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)

[View source]

6071
6072
6073
# File 'lib/HDLRuby/hruby_low.rb', line 6071

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.

[View source]

6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
# File 'lib/HDLRuby/hruby_low.rb', line 6003

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.

[View source]

6043
6044
6045
6046
6047
6048
6049
# File 'lib/HDLRuby/hruby_low.rb', line 6043

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.

[View source]

6054
6055
6056
6057
6058
6059
6060
6061
6062
# File 'lib/HDLRuby/hruby_low.rb', line 6054

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)
[View source]

6019
6020
6021
6022
6023
6024
6025
6026
6027
# File 'lib/HDLRuby/hruby_low.rb', line 6019

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.

[View source]

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)
[View source]

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

def from_systemI?
    return self.ref.from_systemI?
end

#hashObject

Hash function.

[View source]

6030
6031
6032
# File 'lib/HDLRuby/hruby_low.rb', line 6030

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

#immutable?Boolean

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

Returns:

  • (Boolean)
[View source]

5995
5996
5997
5998
# File 'lib/HDLRuby/hruby_low.rb', line 5995

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.

[View source]

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.

[View source]

6037
6038
6039
6040
# File 'lib/HDLRuby/hruby_low.rb', line 6037

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.

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

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)

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
# File 'lib/HDLRuby/hruby_verilog.rb', line 1544

def to_verilog
    # return "#{self.ref.to_verilog}[#{self.index.to_verilog}]"
    if self.ref.is_a?(RefName) then
        return "#{self.ref.to_verilog}[#{self.index.to_verilog}]"
    else
        # No a pure signal, need to use a function for accessing.
        at = self.ref.type.to_verilog
        rt = self.type.to_verilog
        IndexersI.add(at,rt)
        return "#{IndexersI.indexer_name(at,rt)}(#{self.ref.to_verilog},#{self.index.to_verilog})"
    end
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.

[View source]

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

#to_viz_namesObject

Get the port names for visualization from the expression.

[View source]

4959
4960
4961
# File 'lib/HDLRuby/hruby_viz.rb', line 4959

def to_viz_names
  return self.ref.to_viz_names + self.index.to_viz_names
end

#to_viz_node(parent) ⇒ Object

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

[View source]

4964
4965
4966
4967
4968
4969
4970
4971
4972
# File 'lib/HDLRuby/hruby_viz.rb', line 4964

def to_viz_node(parent)
  # Create the viz node.
  node = HDLRuby::Viz::Node.new(:[],parent)
  # Generate the base.
  self.ref.to_viz_node(node)
  # Generate the index.
  self.index.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)
[View source]

6065
6066
6067
6068
# File 'lib/HDLRuby/hruby_low.rb', line 6065

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