Class: HDLRuby::Low::Cast
- Inherits:
-
Expression
- Object
- Base::Expression
- 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
Extends the Cast class with functionality for extracting expressions from 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.
198 199 200 201 |
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 198 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.
184 185 186 187 188 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 |
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 184 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.
241 242 243 244 245 246 247 248 249 250 |
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 241 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)
2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 |
# File 'lib/HDLRuby/hruby_low2c.rb', line 2332 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.
567 568 569 570 |
# File 'lib/HDLRuby/hruby_low2hdr.rb', line 567 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.
402 403 404 |
# File 'lib/HDLRuby/hruby_low2high.rb', line 402 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.
1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 |
# File 'lib/HDLRuby/hruby_verilog.rb', line 1738 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.
1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 |
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1217 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 |