Class: HDLRuby::Low::Cast
- Inherits:
-
Expression
- Object
- Expression
- HDLRuby::Low::Cast
- Includes:
- OneChildMutable
- Defined in:
- 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_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 cast.
Direct Known Subclasses
Constant Summary
Constants included from Low2Symbol
Low2Symbol::Low2SymbolPrefix, Low2Symbol::Low2SymbolTable, Low2Symbol::Symbol2LowTable
Instance Attribute Summary collapse
-
#child ⇒ Object
readonly
The child.
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 value (deeply).
-
#each_deep(&ruby_block) ⇒ Object
Iterates over each object deeply.
-
#each_node(&ruby_block) ⇒ Object
(also: #each_expression)
Iterates over the expression children if any.
-
#each_node_deep(&ruby_block) ⇒ Object
Iterates over the nodes deeply if any.
-
#each_ref_deep(&ruby_block) ⇒ Object
Iterates over all the references encountered in the expression.
-
#eql?(obj) ⇒ Boolean
Comparison for hash: structural comparison.
-
#explicit_types(type = nil) ⇒ Object
Explicit the types conversions in the cast where +type+ is the expected type of the condition if any.
-
#hash ⇒ Object
Hash function.
-
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.).
-
#initialize(type, child) ⇒ Cast
constructor
Creates a new cast of +child+ to +type+.
-
#to_c(res, level = 0) ⇒ Object
return res end Generates the C text of the equivalent HDLRuby code.
-
#to_hdr(level = 0) ⇒ Object
Generates the text of the equivalent hdr text.
-
#to_high ⇒ Object
Creates a new high cast expression.
-
#to_verilog ⇒ Object
Converts the system to Verilog code.
-
#to_vhdl(level = 0) ⇒ 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 included from OneChildMutable
#map_nodes!, #replace_expressions!, #set_child!
Methods inherited from Expression
#boolean?, #break_types!, #extract_selects_to!, #fix_scope_refnames!, #leftvalue?, #map_nodes!, #replace_expressions!, #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, child) ⇒ Cast
Creates a new cast of +child+ to +type+.
5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 |
# File 'lib/HDLRuby/hruby_low.rb', line 5108 def initialize(type,child) # Create the expression and set the type super(type) # Check and set the child. unless child.is_a?(Expression) raise AnyError,"Invalid class for an expression: #{child.class}" end @child = child # And set its parent. child.parent = self end |
Instance Attribute Details
#child ⇒ Object (readonly)
The child
5105 5106 5107 |
# File 'lib/HDLRuby/hruby_low.rb', line 5105 def child @child end |
Instance Method Details
#boolean_in_assign2select ⇒ Object
Converts booleans in assignments to select operators.
204 205 206 207 |
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 204 def boolean_in_assign2select # Recurse on the child. return Cast.new(self.type,self.child.boolean_in_assign2select) end |
#casts_without_expression! ⇒ Object
Extracts the expressions from the casts.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 189 def casts_without_expression! # Recurse on the child. nchild = self.child.casts_without_expression! nchild.parent = nil # Process the cast. unless (nchild.is_a?(Ref)) then # Need to extract the child. # Create signal holding the child. stmnt = self.statement if (stmnt.is_a?(Connection)) then # Specific case of connections: need to build # a new block. scop = stmnt.parent scop.delete_connection!(stmnt) stmnt = Transmit.new(stmnt.left.clone, stmnt.right.clone) blk = Block.new(:seq) scop.add_behavior(Behavior.new(blk)) blk.add_statement(stmnt) else blk = stmnt.block end name = HDLRuby.uniq_name typ = nchild.type sig = blk.add_inner(SignalI.new(name,typ)) # Add a statement assigning the child to the new signal. nref = RefName.new(typ,RefThis.new,name) nstmnt = Transmit.new(nref,nchild) idx = blk.each_statement.find_index(stmnt) blk.insert_statement!(idx,nstmnt) # Replace the child by a reference to the created # signal. nchild = nref.clone end return Cast.new(self.type,nchild) end |
#clone ⇒ Object
Clones the value (deeply)
5194 5195 5196 |
# File 'lib/HDLRuby/hruby_low.rb', line 5194 def clone return Cast.new(@type,@child.clone) end |
#each_deep(&ruby_block) ⇒ Object
Iterates over each object deeply.
Returns an enumerator if no ruby block is given.
5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 |
# File 'lib/HDLRuby/hruby_low.rb', line 5129 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 child. self.child.each_deep(&ruby_block) end |
#each_node(&ruby_block) ⇒ Object Also known as: each_expression
Iterates over the expression children if any.
5156 5157 5158 5159 5160 5161 |
# File 'lib/HDLRuby/hruby_low.rb', line 5156 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 child. ruby_block.call(@child) end |
#each_node_deep(&ruby_block) ⇒ Object
Iterates over the nodes deeply if any.
5166 5167 5168 5169 5170 5171 5172 5173 |
# File 'lib/HDLRuby/hruby_low.rb', line 5166 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 child. @child.each_node_deep(&ruby_block) end |
#each_ref_deep(&ruby_block) ⇒ Object
Iterates over all the references encountered in the expression.
NOTE: do not iterate inside the references.
5178 5179 5180 5181 5182 5183 5184 5185 |
# File 'lib/HDLRuby/hruby_low.rb', line 5178 def each_ref_deep(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_ref_deep) unless ruby_block # puts "each_ref_deep for Unary" # A ruby block? # Recurse on the child. @child.each_ref_deep(&ruby_block) end |
#eql?(obj) ⇒ Boolean
Comparison for hash: structural comparison.
5141 5142 5143 5144 5145 5146 5147 5148 |
# File 'lib/HDLRuby/hruby_low.rb', line 5141 def eql?(obj) # General comparison. return false unless super(obj) # Specific comparison. return false unless obj.is_a?(Cast) return false unless @child.eql?(obj.child) return true end |
#explicit_types(type = nil) ⇒ Object
Explicit the types conversions in the cast where +type+ is the expected type of the condition if any.
261 262 263 264 265 266 267 268 269 270 |
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 261 def explicit_types(type = nil) # Does the type match the cast? if type && !self.type.eql?(type) then # No, Recurse on the child tomatch the type. return self.child.explicit_types(type) else # No simply recurse on the child with the cast's type. return self.child.explicit_types(self.type) end end |
#hash ⇒ Object
Hash function.
5151 5152 5153 |
# File 'lib/HDLRuby/hruby_low.rb', line 5151 def hash return [super,@child].hash end |
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.)
5121 5122 5123 5124 |
# File 'lib/HDLRuby/hruby_low.rb', line 5121 def immutable? # Immutable if the child is immutable. return child.immutable? end |
#to_c(res, level = 0) ⇒ Object
return res end Generates the C text of the equivalent HDLRuby code. +level+ is the hierachical level of the object. def to_c(level = 0)
2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2344 def to_c(res,level = 0) # Save the value pool state. res << (" " * (level*3)) << "PV;\n" # Generate the child. self.child.to_c(res,level) res << (" " * (level*3)) # res << "d=cast(d," res << "cast(" self.type.to_c(res,level+1) res << ");\n" # Restore the value pool state. res << (" " * (level*3)) << "RV;\n" return res end |
#to_hdr(level = 0) ⇒ Object
Generates the text of the equivalent hdr text. +level+ is the hierachical level of the object.
582 583 584 585 |
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 582 def to_hdr(level = 0) return self.child.to_hdr(level) + ".as(" + self.type.to_hdr(level) + ")" end |
#to_high ⇒ Object
Creates a new high cast expression.
434 435 436 |
# File 'lib/HDLRuby/hruby_low2high.rb', line 434 def to_high return HDLRuby::High::Cast(self.type.to_high, self.child.to_high) end |
#to_verilog ⇒ Object
Converts the system to Verilog code. NOTE: the cast is rounded up size bit-width cast is not supported by traditional verilog.
1858 1859 1860 1861 1862 1863 1864 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 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1858 def to_verilog if self.child.is_a?(Value) then return self.child.to_verilog end # Get the type widths, used for computing extensions or truncations. cw = self.child.type.width sw = self.type.width if self.type.signed? then # Need to sign extend. if cw == 1 then return "$signed({#{sw}{#{self.child.to_verilog}}})" elsif (sw>cw) then # return "$signed({{#{sw-cw}{#{self.child.to_verilog}[#{cw-1}]}}," + "#{self.child.to_verilog}})" if self.child.is_a?(RefName) then return "$signed({{#{sw-cw}{#{self.child.to_verilog}[#{cw-1}]}}," + "#{self.child.to_verilog}})" else # No a pure signal, need to use a function for accessing. at = self.child.type.to_verilog rt = bit.to_verilog IndexersI.add(at,rt) return "$signed({{#{sw-cw}{#{IndexersI.indexer_name(at,rt)}(#{self.child.to_verilog},#{cw-1})}}," + "#{self.child.to_verilog}})" end elsif (sw<cw) then # Need to truncate # return "$signed(#{self.child.to_verilog}[#{sw-1}:0])" TruncersI.add((cw-1)..0,(sw-1)..0) return "$signed(#{TruncersI.truncer_name((cw-1)..0,(sw-1)..0)}(#{self.child.to_verilog}))" else # Only enforce signed. return "$signed(#{self.child.to_verilog})" end else if (sw>cw) then # Need to extend. return "$unsigned({{#{sw-cw}{1'b0}},#{self.child.to_verilog}})" elsif (sw<cw) then # Need to truncate # return "$unsigned(#{self.child.to_verilog}[#{sw-1}:0])" TruncersI.add((cw-1)..0,(sw-1)..0) return "$unsigned(#{TruncersI.truncer_name((cw-1)..0,(sw-1)..0)}(#{self.child.to_verilog}))" else # Only enforce signed. return "$unsigned(#{self.child.to_verilog})" end end end |
#to_vhdl(level = 0) ⇒ Object
Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.
1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1241 def to_vhdl(level = 0) if type.class == TypeVector then case type.base.name when :bit return "std_logic_vector(resize(unsigned(" + self.child.to_vhdl(level) + ")," + (type.range.first-type.range.last+1).abs.to_s + "))" when :signed return "resize(signed(" + self.child.to_vhdl(level) + ")," + (type.range.first-type.range.last+1).abs.to_s + ")" when :unsigned return "resize(unsigned(" + self.child.to_vhdl(level) + ")," + (type.range.first-type.range.last+1).abs.to_s + ")" else raise "Intenal error: convertion to #{type.class} not supported yet for VHDL conversion." end elsif [:bit,:signed,:unsigned].include?(type.name) then # No conversion required. return self.child.to_vhdl(level) else raise "Intenal error: convertion to #{type.class} not supported yet for VHDL conversion." end end |
#use_name?(*names) ⇒ Boolean
Tell if the expression includes a signal whose name is one of +names+.
5188 5189 5190 5191 |
# File 'lib/HDLRuby/hruby_low.rb', line 5188 def use_name?(*names) # Recurse on the child. return @child.use_name?(*names) end |