Class: HDLRuby::Low::RefRange
- Inherits:
-
Ref
- Object
- Expression
- Ref
- HDLRuby::Low::RefRange
- Defined in:
- lib/HDLRuby/hruby_low.rb,
lib/HDLRuby/hruby_viz.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
Describes a range reference.
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
(also: #map_expressions!)
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.
-
#to_viz_names ⇒ Object
Get the port names for visualization from the expression.
-
#to_viz_node(parent) ⇒ Object
Converts the index reference to a Viz flow node under +parent+.
-
#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!, #fix_scope_refnames!, #leftvalue?, #replace_names!, #rightvalue?, #set_type!, #signal2subs!, #statement, #to_c_expr
Methods included from Low2Symbol
Methods included from Hparent
#absolute_ref, #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)
6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 |
# File 'lib/HDLRuby/hruby_low.rb', line 6062 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 # Clears the parent of first and last that is automatically added # by Ruby when creating a range. first.no_parent! if first.is_a?(Hparent) last.no_parent! if last.is_a?(Hparent) # And set their parents. first.parent = last.parent = self end |
Instance Attribute Details
#range ⇒ Object (readonly)
The access range.
6058 6059 6060 |
# File 'lib/HDLRuby/hruby_low.rb', line 6058 def range @range end |
#ref ⇒ Object (readonly)
The accessed reference.
6055 6056 6057 |
# File 'lib/HDLRuby/hruby_low.rb', line 6055 def ref @ref end |
Instance Method Details
#boolean_in_assign2select ⇒ Object
Converts booleans in assignments to select operators.
324 325 326 327 328 329 330 |
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 324 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.
333 334 335 336 337 338 339 340 341 342 343 |
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 333 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)
6178 6179 6180 6181 |
# File 'lib/HDLRuby/hruby_low.rb', line 6178 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.
6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 |
# File 'lib/HDLRuby/hruby_low.rb', line 6100 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.
6147 6148 6149 6150 6151 6152 6153 6154 |
# File 'lib/HDLRuby/hruby_low.rb', line 6147 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.
6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 |
# File 'lib/HDLRuby/hruby_low.rb', line 6159 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).
6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 |
# File 'lib/HDLRuby/hruby_low.rb', line 6122 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.
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 |
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 454 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.
161 162 163 |
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 161 def from_systemI? return self.ref.from_systemI? end |
#hash ⇒ Object
Hash function.
6134 6135 6136 |
# File 'lib/HDLRuby/hruby_low.rb', line 6134 def hash return [super,@range,@ref].hash end |
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.)
6092 6093 6094 6095 |
# File 'lib/HDLRuby/hruby_low.rb', line 6092 def immutable? # Immutable if the ref is immutable. return self.ref.immutable? end |
#map_nodes!(&ruby_block) ⇒ Object Also known as: map_expressions!
Maps on the children.
1812 1813 1814 1815 1816 1817 1818 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1812 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.
6141 6142 6143 6144 |
# File 'lib/HDLRuby/hruby_low.rb', line 6141 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.
1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1828 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.
168 169 170 |
# File 'lib/HDLRuby/hruby_low_resolve.rb', line 168 def resolve return self.ref.resolve end |
#set_range!(range) ⇒ Object
Sets the range.
1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1795 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.
1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 |
# File 'lib/HDLRuby/hruby_low_mutable.rb', line 1783 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
3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 3028 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)
3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 3069 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.
718 719 720 721 |
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 718 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.
523 524 525 526 527 |
# File 'lib/HDLRuby/hruby_low2high.rb', line 523 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.
1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1579 def to_verilog(unknown = false) if self.ref.is_a?(RefName) then return "#{self.ref.to_verilog}[#{self.range.first.to_getrange}:#{self.range.last.to_getrange}]" else # No a pure signal, need to use a function for accessing. # sr = self.range.first.to_i..self.range.last.to_i # cr = (self.type.width-1)..0 sr = (self.range.first.to_i+1)*self.ref.type.base.width-1.. self.range.last.to_i*self.ref.type.base.width cr = (self.ref.type.width-1)..0 TruncersI.add(cr,sr) return "#{TruncersI.truncer_name(cr,sr)}(#{self.ref.to_verilog})" end 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.
1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1507 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 |
#to_viz_names ⇒ Object
Get the port names for visualization from the expression.
4978 4979 4980 4981 |
# File 'lib/HDLRuby/hruby_viz.rb', line 4978 def to_viz_names return self.ref.to_viz_names + self.range.first.to_viz_names + self.range.last.to_viz_names end |
#to_viz_node(parent) ⇒ Object
Converts the index reference to a Viz flow node under +parent+.
4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 |
# File 'lib/HDLRuby/hruby_viz.rb', line 4984 def to_viz_node(parent) # Create the viz node. node = HDLRuby::Viz::Node.new(:[],parent) # Generate the base. self.ref.to_viz_node(node) # Generate the range. self.range.first.to_viz_node(node) self.range.last.to_viz_node(node) return node end |
#use_name?(*names) ⇒ Boolean
Tell if the expression includes a signal whose name is one of +names+.
6171 6172 6173 6174 6175 |
# File 'lib/HDLRuby/hruby_low.rb', line 6171 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 |