Class: HDLRuby::Low::Cast

Inherits:
Expression
  • Object
show all
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

High::Cast

Constant Summary

Constants included from Low2Symbol

Low2Symbol::Low2SymbolPrefix, Low2Symbol::Low2SymbolTable, Low2Symbol::Symbol2LowTable

Instance Attribute Summary collapse

Attributes inherited from Expression

#type

Attributes included from Hparent

#parent

Instance Method Summary collapse

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!, #statement, #to_c_expr

Methods included from Low2Symbol

#to_sym

Methods included from Hparent

#hierarchy, #scope

Constructor Details

#initialize(type, child) ⇒ Cast

Creates a new cast of +child+ to +type+.



4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
# File 'lib/HDLRuby/hruby_low.rb', line 4756

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

#childObject (readonly)

The child



4753
4754
4755
# File 'lib/HDLRuby/hruby_low.rb', line 4753

def child
  @child
end

Instance Method Details

#boolean_in_assign2selectObject

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

#cloneObject

Clones the value (deeply)



4842
4843
4844
# File 'lib/HDLRuby/hruby_low.rb', line 4842

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.



4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
# File 'lib/HDLRuby/hruby_low.rb', line 4777

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.



4804
4805
4806
4807
4808
4809
# File 'lib/HDLRuby/hruby_low.rb', line 4804

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.



4814
4815
4816
4817
4818
4819
4820
4821
# File 'lib/HDLRuby/hruby_low.rb', line 4814

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.



4826
4827
4828
4829
4830
4831
4832
4833
# File 'lib/HDLRuby/hruby_low.rb', line 4826

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.

Returns:

  • (Boolean)


4789
4790
4791
4792
4793
4794
4795
4796
# File 'lib/HDLRuby/hruby_low.rb', line 4789

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

#hashObject

Hash function.



4799
4800
4801
# File 'lib/HDLRuby/hruby_low.rb', line 4799

def hash
    return [super,@child].hash
end

#immutable?Boolean

Tells if the expression is immutable (cannot be written.)

Returns:

  • (Boolean)


4769
4770
4771
4772
# File 'lib/HDLRuby/hruby_low.rb', line 4769

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)



2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
# File 'lib/HDLRuby/hruby_low2c.rb', line 2160

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_highObject

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_verilogObject

Converts the system to Verilog code. NOTE: the cast is rounded up size bit-width cast is not supported by traditional verilog.



1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
# File 'lib/HDLRuby/hruby_verilog.rb', line 1704

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.



1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1216

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+.

Returns:

  • (Boolean)


4836
4837
4838
4839
# File 'lib/HDLRuby/hruby_low.rb', line 4836

def use_name?(*names)
    # Recurse on the child.
    return @child.use_name?(*names)
end