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
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.
-
#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.
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)
4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 |
# File 'lib/HDLRuby/hruby_low.rb', line 4636 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.
4632 4633 4634 |
# File 'lib/HDLRuby/hruby_low.rb', line 4632 def range @range end |
#ref ⇒ Object (readonly)
The accessed reference.
4629 4630 4631 |
# File 'lib/HDLRuby/hruby_low.rb', line 4629 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 |
#clone ⇒ Object
Clones the range references (deeply)
4714 4715 4716 4717 |
# File 'lib/HDLRuby/hruby_low.rb', line 4714 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.
4690 4691 4692 4693 4694 4695 4696 4697 |
# File 'lib/HDLRuby/hruby_low.rb', line 4690 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.
4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 |
# File 'lib/HDLRuby/hruby_low.rb', line 4702 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).
4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 |
# File 'lib/HDLRuby/hruby_low.rb', line 4665 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.
4677 4678 4679 |
# File 'lib/HDLRuby/hruby_low.rb', line 4677 def hash return [super,@range,@ref].hash end |
#map_nodes!(&ruby_block) ⇒ Object
Maps on the children.
1681 1682 1683 1684 1685 1686 1687 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1681 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.
4684 4685 4686 4687 |
# File 'lib/HDLRuby/hruby_low.rb', line 4684 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.
1695 1696 1697 1698 1699 1700 1701 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 1732 1733 1734 1735 1736 1737 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1695 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.
1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1664 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.
1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1652 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.
1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 1901 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.
1948 1949 1950 1951 1952 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 1948 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.
1362 1363 1364 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1362 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 |