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_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
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_deep(&ruby_block) ⇒ Object
Iterates over each object 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.
-
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.).
-
#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.
-
#resolve ⇒ Object
Resolves the name of the reference (if any) and return the corresponding object.
-
#set_range!(range) ⇒ Object
Sets the range.
-
#set_ref!(ref) ⇒ Object
Sets the base reference.
-
#to_c(res, level = 0, left = false) ⇒ Object
Generates the C text of the equivalent HDLRuby code.
-
#to_c_signal(res, level = 0) ⇒ Object
Generates the C text for reference as left value to a signal.
-
#to_hdr(level = 0) ⇒ Object
Generates the text of the equivalent hdr text.
-
#to_high ⇒ Object
Creates a new high range reference.
-
#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, #to_c_expr
Methods included from Low2Symbol
Methods included from Hparent
#hierarchy, #no_parent!, #scope
Constructor Details
#initialize(type, ref, range) ⇒ RefRange
Create a new range reference with +type+ accessing +ref+ at +range+. def initialize(ref,range)
5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 |
# File 'lib/HDLRuby/hruby_low.rb', line 5712 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.
5708 5709 5710 |
# File 'lib/HDLRuby/hruby_low.rb', line 5708 def range @range end |
#ref ⇒ Object (readonly)
The accessed reference.
5705 5706 5707 |
# File 'lib/HDLRuby/hruby_low.rb', line 5705 def ref @ref end |
Instance Method Details
#boolean_in_assign2select ⇒ Object
Converts booleans in assignments to select operators.
312 313 314 315 316 317 318 |
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 312 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.
323 324 325 326 327 328 329 330 331 332 333 |
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 323 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) self.set_ref!(self.ref.casts_without_expression!) self.set_range!(self.range.first.casts_without_expression! .. self.range.last.casts_without_expression!) return self end |
#clone ⇒ Object
Clones the range references (deeply)
5824 5825 5826 5827 |
# File 'lib/HDLRuby/hruby_low.rb', line 5824 def clone return RefRange.new(@type, @ref.clone, (@range.first.clone)..(@range.last.clone) ) end |
#each_deep(&ruby_block) ⇒ Object
Iterates over each object deeply.
Returns an enumerator if no ruby block is given.
5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 |
# File 'lib/HDLRuby/hruby_low.rb', line 5746 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_node(&ruby_block) ⇒ Object Also known as: each_expression
Iterates over the reference children if any.
5793 5794 5795 5796 5797 5798 5799 5800 |
# File 'lib/HDLRuby/hruby_low.rb', line 5793 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.
5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 |
# File 'lib/HDLRuby/hruby_low.rb', line 5805 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).
5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 |
# File 'lib/HDLRuby/hruby_low.rb', line 5768 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.
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 |
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 424 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.
151 152 153 |
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 151 def from_systemI? return self.ref.from_systemI? end |
#hash ⇒ Object
Hash function.
5780 5781 5782 |
# File 'lib/HDLRuby/hruby_low.rb', line 5780 def hash return [super,@range,@ref].hash end |
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.)
5738 5739 5740 5741 |
# File 'lib/HDLRuby/hruby_low.rb', line 5738 def immutable? # Immutable if the ref is immutable. return self.ref.immutable? end |
#map_nodes!(&ruby_block) ⇒ Object
Maps on the children.
1851 1852 1853 1854 1855 1856 1857 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1851 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.
5787 5788 5789 5790 |
# File 'lib/HDLRuby/hruby_low.rb', line 5787 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.
1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1865 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 ⇒ Object
Resolves the name of the reference (if any) and return the corresponding object. NOTE: return nil if could not resolve.
158 159 160 |
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 158 def resolve return self.ref.resolve end |
#set_range!(range) ⇒ Object
Sets the range.
1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1834 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.
1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1822 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(res, level = 0, left = false) ⇒ Object
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.
def to_c(level = 0, left = false)
def to_c(res,level = 0, left = false) # Decide if it is a read or a write command = left ? "write" : "read" # res = "( 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" res << "ref = " self.ref.to_c(res,level+2) res << ";\n" # Compute the range. res << (" " * ((level+1)*3)) # res << "first = value2integer(#HDLRuby::Low::RefRange.selfself.rangeself.range.firstself.range.first.to_c(level+2));\n" res << "first = value2integer(" self.range.first.to_c(res,level+2) res << ");\n" res << (" " * ((level+1)*3)) # res << "last = value2integer(#HDLRuby::Low::RefRange.selfself.rangeself.range.lastself.range.last.to_c(level+2));\n" res << "last = value2integer(" self.range.last.to_c(res,level+2) res << ");\n" # Make the access. res << (" " * ((level+1)*3)) # puts "#command_range with first=#HDLRuby::Low::RefRange.selfself.rangeself.range.first and last=#HDLRuby::Low::RefRange.selfself.rangeself.range.last" # res << "dst = #command_range(ref,first,last,#HDLRuby::Low::RefRange.selfself.typeself.type.baseself.type.base.to_c(level),dst);\n" res << "dst = #command_range(ref,first,last," self.type.base.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
2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2871 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) # res << (" " * (level*3)) # Compute the range. self.range.first.to_c(res,level) self.range.last.to_c(res,level) # Make the access. res << (" " * (level*3)) if left then res << "swriteR(" else res << "sreadR(" end self.type.base.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) # return "make_ref_rangeS(#HDLRuby::Low::RefRange.selfself.refself.ref.to_c_signal(level)," + # "value2integer(#HDLRuby::Low::RefRange.selfself.rangeself.range.firstself.range.first.to_c(level)),value2integer(#HDLRuby::Low::RefRange.selfself.rangeself.range.lastself.range.last.to_c(level)))" res << "make_ref_rangeS(" self.ref.to_c_signal(res,level) res << ",value2integer(" self.range.first.to_c(res,level) res << "),value2integer(" self.range.last.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)
2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2912 def to_c_signal(res,level = 0) res << "make_ref_rangeS(" self.ref.to_c_signal(res,level) res << "," self.type.base.to_c(res,level) res << ",value2integer(({\n" self.range.first.to_c(res,level) res << " " * ((level+1)*3) res << "pop();})" res << "),value2integer(({\n" self.range.last.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.
695 696 697 698 |
# 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 ⇒ Object
Creates a new high range reference.
484 485 486 487 488 |
# 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) ⇒ Object
Converts the system to Verilog code.
1492 1493 1494 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1492 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.
1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1474 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+.
5817 5818 5819 5820 5821 |
# File 'lib/HDLRuby/hruby_low.rb', line 5817 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 |