class HDLRuby::Low::RefRange

Describes a range reference.

Describes a range reference.

Extends the RefRange class with generation of C text.

Extends the RefRange class with generation of hdr text.

Add the conversion to high.

Extends the RefRange class with generation of HDLRuby::High text.

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

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

Extends the RefRange class with fixing of types and constants.

Describes a range reference.

Extends RefRange with the capability of finding the object it refered to.

Necessary for displaying bit width (eg, specify and assign).

Attributes

range[R]

The access range.

ref[R]

The accessed reference.

Public Class Methods

new(type,ref,range) click to toggle source

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

Calls superclass method
# File lib/HDLRuby/hruby_low.rb, line 5444
def initialize(type,ref,range)
    super(type)
    # Check and set the refered object.
    # 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 range.
    first = range.first
    unless first.is_a?(Expression) then
        raise AnyError,
              "Invalid class for a range first: #{first.class}."
    end
    last = range.last
    unless last.is_a?(Expression) then
        raise AnyError, "Invalid class for a range last: #{last.class}."
    end
    @range = first..last
    # And set their parents.
    first.parent = last.parent = self
end

Public Instance Methods

boolean_in_assign2select() click to toggle source

Converts booleans in assignments to select operators.

# File lib/HDLRuby/hruby_low_bool2select.rb, line 300
def boolean_in_assign2select
    # Recurse on the sub references.
    return RefRange.new(self.type,
                        self.ref.boolean_in_assign2select,
                        self.range.first.boolean_in_assign2select ..
                        self.range.last.boolean_in_assign2select)
end
casts_without_expression() click to toggle source

Extracts the expressions from the casts.

# File lib/HDLRuby/hruby_low_casts_without_expression.rb, line 308
def casts_without_expression
    # Recurse on the sub references.
    return RefRange.new(self.type,
                        self.ref.casts_without_expression,
                        self.range.first.casts_without_expression ..
                        self.range.last.casts_without_expression)
end
clone() click to toggle source

Clones the range references (deeply)

# File lib/HDLRuby/hruby_low.rb, line 5556
def clone
    return RefRange.new(@type, @ref.clone,
                        (@range.first.clone)..(@range.last.clone) )
end
each_deep(&ruby_block) click to toggle source

Iterates over each object deeply.

Returns an enumerator if no ruby block is given.

# File lib/HDLRuby/hruby_low.rb, line 5478
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 range if possible.
    if self.range.first.respond_to?(:each_deep) then
        self.range.first.each_deep(&ruby_block)
    end
    if self.range.last.respond_to?(:each_deep) then
        self.range.last.each_deep(&ruby_block)
    end
end
each_expression(&ruby_block)
Alias for: each_node
each_node(&ruby_block) click to toggle source

Iterates over the reference children if any.

# File lib/HDLRuby/hruby_low.rb, line 5525
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 ranfe and the ref.
    ruby_block.call(@range.first)
    ruby_block.call(@range.last)
    ruby_block.call(@ref)
end
Also aliased as: each_expression
each_node_deep(&ruby_block) click to toggle source

Iterates over the nodes deeply if any.

# File lib/HDLRuby/hruby_low.rb, line 5537
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.
    @range.first.each_node_deep(&ruby_block)
    @range.last.each_node_deep(&ruby_block)
    @ref.each_node_deep(&ruby_block)
end
eql?(obj) click to toggle source

Comparison for hash: structural comparison.

NOTE: ranges are assumed to be flattened (a range of range is a range of same level).

Calls superclass method
# File lib/HDLRuby/hruby_low.rb, line 5500
def eql?(obj)
    # General comparison.
    return false unless super(obj)
    # Specific comparison.
    return false unless obj.is_a?(RefRange)
    return false unless @range.first.eql?(obj.range.first)
    return false unless @range.last.eql?(obj.range.last)
    return false unless @ref.eql?(obj.ref)
    return true
end
explicit_types(type = nil) click to toggle source

Explicit the types conversions in the range ref where type is the expected type of the condition if any.

# File lib/HDLRuby/hruby_low_fix_types.rb, line 405
def explicit_types(type = nil)
    # Is there a type to match ?
    if type then
        # Regenerate the reference and cast it.
        return Cast.new(type,
                    RefRange.new(self.type,self.ref.explicit_types,
                            self.range.first.explicit_types ..
                            self.range.last.explicit_types))
    else
        # No, recurse with the type of the current range ref.
        return RefRange.new(self.type,
                            self.ref.explicit_types,
                            self.range.first.explicit_types ..
                            self.range.last.explicit_types)
    end
end
from_systemI?() click to toggle source

Tells if it is a reference to a systemI signal.

# File lib/HDLRuby/hruby_low_resolve.rb, line 126
def from_systemI?
    return self.ref.from_systemI?
end
hash() click to toggle source

Hash function.

Calls superclass method
# File lib/HDLRuby/hruby_low.rb, line 5512
def hash
    return [super,@range,@ref].hash
end
immutable?() click to toggle source

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

# File lib/HDLRuby/hruby_low.rb, line 5470
def immutable?
    # Immutable if the ref is immutable.
    return self.ref.immutable?
end
map_nodes!(&ruby_block) click to toggle source

Maps on the children.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1839
def map_nodes!(&ruby_block)
    @range = ruby_block.call(@range.first)..ruby_block.call(@range.last)
    @range.first.parent = self unless @range.first.parent
    @range.last.parent = self unless @range.last.parent
    @ref   = ruby_block.call(@ref)
    @ref.parent = self unless @ref.parent
end
path_each(&ruby_block) click to toggle source

Iterates over the names of the path indicated by the reference.

Returns an enumerator if no ruby block is given.

# File lib/HDLRuby/hruby_low.rb, line 5519
def path_each(&ruby_block)
    # Recurse on the base reference.
    return ref.path_each(&ruby_block)
end
replace_expressions!(node2rep) click to toggle source

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.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1853
def replace_expressions!(node2rep)
    # First recurse on the ref.
    res = self.ref.replace_expressions!(node2rep)
    # And and the range.
    res = self.range.first.replace_expressions!(node2rep)
    res = self.range.last.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 range first?
    range = self.range
    rep = node2rep[range.first]
    if rep then
        # Yes, do it.
        rep = rep.clone
        node = range.first
        # node.set_parent!(nil)
        range.first = rep
        # And register the replacement.
        res[node] = rep
    end
    rep = node2rep[range.last]
    if rep then
        # Yes, do it.
        rep = rep.clone
        node = range.last
        # node.set_parent!(nil)
        range.last = rep
        # And register the replacement.
        res[node] = rep
    end
    self.set_range!(range)
    return res
end
resolve() click to toggle source

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

# File lib/HDLRuby/hruby_low_resolve.rb, line 133
def resolve
    return self.ref.resolve
end
set_range!(range) click to toggle source

Sets the range.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1822
def set_range!(range)
    # Check and set the range.
    first = range.first
    unless first.is_a?(Expression) then
        raise AnyError,
              "Invalid class for a range first: #{first.class}."
    end
    last = range.last
    unless last.is_a?(Expression) then
        raise AnyError, "Invalid class for a range last: #{last.class}."
    end
    @range = first..last
    # And set their parents.
    first.parent = last.parent = self
end
set_ref!(ref) click to toggle source

Sets the base reference.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1810
def set_ref!(ref)
    # Check and set the refered object.
    # 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
end
to_c(level = 0, left = false) click to toggle source

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

# File lib/HDLRuby/hruby_low2c.rb, line 1962
def to_c(level = 0, left = false)
    # Decide if it is a read or a write
    command = left ? "write" : "read"
    res = "({\n"
    # Overrides the upper ref and dst...
    # 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 first,last;\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 range.
    res << (" " * ((level+1)*3))
    # res << "first = read64(#{self.range.first.to_c(level+2)});\n"
    res << "first = value2integer(#{self.range.first.to_c(level+2)});\n"
    res << (" " * ((level+1)*3))
    # res << "last = read64(#{self.range.last.to_c(level+2)});\n"
    res << "last = value2integer(#{self.range.last.to_c(level+2)});\n"
    # Make the access.
    res << (" " * ((level+1)*3))
    # res << "dst = #{command}_range(ref,first,last,#{self.ref.type.base.to_c(level)},dst);\n"
    # puts "will read_range for #{self.ref.name} with width=#{self.ref.type.width} with base width=#{self.ref.type.base.width} with range=#{self.ref.type.range} with range=#{self.range.first.content}..#{self.range.last.content}"
    res << "dst = #{command}_range(ref,first,last,#{self.type.base.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) click to toggle source

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

# File lib/HDLRuby/hruby_low2c.rb, line 2000
def to_c_signal(level = 0)
    # return to_c(level,true)
    return "make_ref_rangeS(#{self.ref.to_c_signal(level)}," +
        "value2integer(#{self.range.first.to_c(level)}),value2integer(#{self.range.last.to_c(level)}))"
end
to_hdr(level = 0) click to toggle source

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

# File lib/HDLRuby/hruby_low2hdr.rb, line 695
def to_hdr(level = 0)
    return self.ref.to_hdr(level) +
        "[(#{self.range.first.to_hdr(level)})..(#{self.range.last.to_hdr(level)})]"
end
to_high() click to toggle source

Creates a new high range reference.

# File lib/HDLRuby/hruby_low2high.rb, line 484
def to_high
    return HDLRuby::High::RefRange.new(self.type.to_high,
                                       self.ref.to_high,
                    self.range.first.to_high..self.range.last.to_high)
end
to_verilog(unknown = false) click to toggle source

Converts the system to Verilog code.

# File lib/HDLRuby/hruby_verilog.rb, line 1418
def to_verilog(unknown = false)
    return "#{self.ref.to_verilog}[#{self.range.first.to_getrange}:#{self.range.last.to_getrange}]"
end
to_vhdl(level = 0, std_logic = false) click to toggle source

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.

# File lib/HDLRuby/hruby_low2vhd.rb, line 1462
def to_vhdl(level = 0, std_logic = false)
    # Generates the direction.
    first = self.range.first
    first = first.content if first.is_a?(Value)
    last = self.range.last
    last = last.content if last.is_a?(Value)
    direction = first >= last ?  "downto " : " to "
    # Generate the reference.
    # Forced std_logic case.
    if std_logic then
        if first == last then
            # No range, single bit access for forcing std_logic.
            return self.ref.to_vhdl(level) +
                "(#{self.range.first.to_vhdl(level)})"
        else
            return self.ref.to_vhdl(level) +
                "((#{self.range.first.to_vhdl(level)}) " +
                direction + "(#{self.range.last.to_vhdl(level)}))(0)"
        end
    else
        return self.ref.to_vhdl(level) +
            "((#{self.range.first.to_vhdl(level)}) " +
            direction + "(#{self.range.last.to_vhdl(level)}))"
    end
end
use_name?(*names) click to toggle source

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

# File lib/HDLRuby/hruby_low.rb, line 5549
def use_name?(*names)
    # Recurse on the range and the reference.
    return @range.first.use_name?(names) ||
           @range.last.use_name?(names)  || @ref.use_name?(*names)
end