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
The access range.
The accessed reference.
Public Class Methods
Create a new range reference with type
accessing ref
at range
. def initialize(ref,range)
# 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
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
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
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
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
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
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
Comparison for hash: structural comparison.
NOTE: ranges are assumed to be flattened (a range of range is a range of same level).
# 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 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
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
function.
# File lib/HDLRuby/hruby_low.rb, line 5512 def hash return [super,@range,@ref].hash end
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
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
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
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
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
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
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
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
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
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
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
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
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
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