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!, #leftvalue?, #map_nodes!, #replace_expressions!, #replace_names!, #rightvalue?, #set_type!, #signal2subs!, #statement, #to_c_expr
Methods included from Low2Symbol
Methods included from Hparent
#hierarchy, #no_parent!, #scope
Constructor Details
#initialize(type, child) ⇒ Cast
Creates a new cast of +child+ to +type+.
4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 |
# File 'lib/HDLRuby/hruby_low.rb', line 4984 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
4981 4982 4983 |
# File 'lib/HDLRuby/hruby_low.rb', line 4981 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)
5070 5071 5072 |
# File 'lib/HDLRuby/hruby_low.rb', line 5070 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.
5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 |
# File 'lib/HDLRuby/hruby_low.rb', line 5005 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.
5032 5033 5034 5035 5036 5037 |
# File 'lib/HDLRuby/hruby_low.rb', line 5032 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.
5042 5043 5044 5045 5046 5047 5048 5049 |
# File 'lib/HDLRuby/hruby_low.rb', line 5042 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.
5054 5055 5056 5057 5058 5059 5060 5061 |
# File 'lib/HDLRuby/hruby_low.rb', line 5054 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.
5017 5018 5019 5020 5021 5022 5023 5024 |
# File 'lib/HDLRuby/hruby_low.rb', line 5017 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.
5027 5028 5029 |
# File 'lib/HDLRuby/hruby_low.rb', line 5027 def hash return [super,@child].hash end |
#immutable? ⇒ Boolean
Tells if the expression is immutable (cannot be written.)
4997 4998 4999 5000 |
# File 'lib/HDLRuby/hruby_low.rb', line 4997 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.
1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1765 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 if (sw>cw) then # Need to sign extend. return "$signed({{#{sw-cw}{#{self.child.to_verilog}[#{cw-1}]}}," + "#{self.child.to_verilog}})" 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+.
5064 5065 5066 5067 |
# File 'lib/HDLRuby/hruby_low.rb', line 5064 def use_name?(*names) # Recurse on the child. return @child.use_name?(*names) end |