Class: HDLRuby::Low::RefRange
- Inherits:
-
Ref
- Object
- Base::Expression
- Expression
- Ref
- HDLRuby::Low::RefRange
- 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,
lib/HDLRuby/hruby_low_casts_without_expression.rb
Overview
Extends the RefRange class with functionality for converting booleans in assignments to select operators.
Direct Known Subclasses
Constant Summary
Constants included from Low2Symbol
Low2Symbol::Low2SymbolPrefix, Low2Symbol::Low2SymbolTable, Low2Symbol::Symbol2LowTable
Instance Attribute Summary collapse
-
#range ⇒ Object
readonly
The access range.
-
#ref ⇒ Object
readonly
The accessed reference.
Attributes inherited from Expression
Attributes included from Hparent
Instance Method Summary collapse
-
#boolean_in_assign2select ⇒ Object
Converts booleans in assignments to select operators.
-
#casts_without_expression ⇒ Object
Extracts the expressions from the casts.
-
#clone ⇒ Object
Clones the range references (deeply).
-
#each_node(&ruby_block) ⇒ Object
(also: #each_expression)
Iterates over the reference children if any.
-
#each_node_deep(&ruby_block) ⇒ Object
Iterates over the nodes deeply if any.
-
#eql?(obj) ⇒ Boolean
Comparison for hash: structural comparison.
-
#explicit_types(type = nil) ⇒ Object
Explicit the types conversions in the range ref where +type+ is the expected type of the condition if any.
-
#from_systemI? ⇒ Boolean
Tells if it is a reference to a systemI signal.
-
#hash ⇒ Object
Hash function.
-
#initialize(type, ref, range) ⇒ RefRange
constructor
Create a new range reference with +type+ accessing +ref+ at +range+.
-
#map_nodes!(&ruby_block) ⇒ Object
Maps on the children.
-
#path_each(&ruby_block) ⇒ Object
Iterates over the names of the path indicated by the reference.
-
#replace_expressions!(node2rep) ⇒ Object
Replaces sub expressions using +node2rep+ table indicating the node to replace and the corresponding replacement.
-
#set_range!(range) ⇒ Object
Sets the range.
-
#set_ref!(ref) ⇒ Object
Sets the base reference.
-
#to_c(level = 0, left = false) ⇒ Object
Generates the C text of the equivalent HDLRuby::High code.
-
#to_c_signal(level = 0) ⇒ Object
Generates the C text for reference as left value to a signal.
-
#to_high(level = 0) ⇒ Object
Generates the text of the equivalent HDLRuby::High code.
-
#to_verilog(unknown = false) ⇒ Object
Converts the system to Verilog code.
-
#to_vhdl(level = 0, std_logic = false) ⇒ Object
Generates the text of the equivalent HDLRuby::High code.
-
#use_name?(*names) ⇒ Boolean
Tell if the expression includes a signal whose name is one of +names+.
Methods inherited from Expression
#boolean?, #break_types!, #each_ref_deep, #extract_selects_to!, #leftvalue?, #replace_names!, #rightvalue?, #set_type!, #statement
Methods included from Low2Symbol
Methods included from Hparent
Constructor Details
#initialize(type, ref, range) ⇒ RefRange
Create a new range reference with +type+ accessing +ref+ at +range+. def initialize(ref,range)
4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 |
# File 'lib/HDLRuby/hruby_low.rb', line 4730 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 |
Instance Attribute Details
#range ⇒ Object (readonly)
The access range.
4726 4727 4728 |
# File 'lib/HDLRuby/hruby_low.rb', line 4726 def range @range end |
#ref ⇒ Object (readonly)
The accessed reference.
4723 4724 4725 |
# File 'lib/HDLRuby/hruby_low.rb', line 4723 def ref @ref end |
Instance Method Details
#boolean_in_assign2select ⇒ Object
Converts booleans in assignments to select operators.
286 287 288 289 290 291 292 |
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 286 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 ⇒ Object
Extracts the expressions from the casts.
294 295 296 297 298 299 300 |
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 294 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 ⇒ Object
Clones the range references (deeply)
4815 4816 4817 4818 |
# File 'lib/HDLRuby/hruby_low.rb', line 4815 def clone return RefRange.new(@type, @ref.clone, (@range.first.clone)..(@range.last.clone) ) end |
#each_node(&ruby_block) ⇒ Object Also known as: each_expression
Iterates over the reference children if any.
4784 4785 4786 4787 4788 4789 4790 4791 |
# File 'lib/HDLRuby/hruby_low.rb', line 4784 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 |
#each_node_deep(&ruby_block) ⇒ Object
Iterates over the nodes deeply if any.
4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 |
# File 'lib/HDLRuby/hruby_low.rb', line 4796 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) ⇒ Boolean
Comparison for hash: structural comparison.
NOTE: ranges are assumed to be flattened (a range of range is a range of same level).
4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 |
# File 'lib/HDLRuby/hruby_low.rb', line 4759 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) ⇒ Object
Explicit the types conversions in the range ref where +type+ is the expected type of the condition if any.
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 |
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 391 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? ⇒ Boolean
Tells if it is a reference to a systemI signal.
105 106 107 |
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 105 def from_systemI? return self.ref.from_systemI? end |
#hash ⇒ Object
Hash function.
4771 4772 4773 |
# File 'lib/HDLRuby/hruby_low.rb', line 4771 def hash return [super,@range,@ref].hash end |
#map_nodes!(&ruby_block) ⇒ Object
Maps on the children.
1769 1770 1771 1772 1773 1774 1775 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1769 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) ⇒ Object
Iterates over the names of the path indicated by the reference.
Returns an enumerator if no ruby block is given.
4778 4779 4780 4781 |
# File 'lib/HDLRuby/hruby_low.rb', line 4778 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.
1783 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 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1783 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 |
#set_range!(range) ⇒ Object
Sets the range.
1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1752 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) ⇒ Object
Sets the base reference.
1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1740 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) ⇒ Object
Generates the C text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object and +left+ tells if it is a left value or not.
1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 1923 def to_c(level = 0, left = false) # if left then # res = "write_range(#{self.ref.to_c(level,left)}," # else # res = "read_range(#{self.ref.to_c(level,left)}," # end # res << "read64(#{self.range.first.to_c(level)})," + # "read64(#{self.range.last.to_c(level)})," + # "#{self.type.base.to_c(level)})" # return res # 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) ⇒ Object
Generates the C text for reference as left value to a signal. +level+ is the hierarchical level of the object.
1970 1971 1972 1973 1974 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 1970 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_high(level = 0) ⇒ Object
Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.
695 696 697 698 |
# File 'lib/HDLRuby/hruby_low2high.rb', line 695 def to_high(level = 0) return self.ref.to_high(level) + "[(#{self.range.first.to_high(level)})..(#{self.range.last.to_high(level)})]" end |
#to_verilog(unknown = false) ⇒ Object
Converts the system to Verilog code.
1431 1432 1433 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1431 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) ⇒ 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.
1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1437 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) ⇒ Boolean
Tell if the expression includes a signal whose name is one of +names+.
4808 4809 4810 4811 4812 |
# File 'lib/HDLRuby/hruby_low.rb', line 4808 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 |