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_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

Overview

Extends the Cast class with functionality for converting booleans in assignments to select operators.

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

Methods included from Low2Symbol

#to_sym

Methods included from Hparent

#scope

Constructor Details

#initialize(type, child) ⇒ Cast

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



3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
# File 'lib/HDLRuby/hruby_low.rb', line 3975

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



3972
3973
3974
# File 'lib/HDLRuby/hruby_low.rb', line 3972

def child
  @child
end

Instance Method Details

#boolean_in_assign2selectObject

Converts booleans in assignments to select operators.



172
173
174
175
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 172

def boolean_in_assign2select
    # Recurse on the child.
    return Cast.new(self.type,self.child.boolean_in_assign2select)
end

#cloneObject

Clones the value (deeply)



4041
4042
4043
# File 'lib/HDLRuby/hruby_low.rb', line 4041

def clone
    return Cast.new(@type,@child.clone)
end

#each_node(&ruby_block) ⇒ Object Also known as: each_expression

Iterates over the expression children if any.



4003
4004
4005
4006
4007
4008
# File 'lib/HDLRuby/hruby_low.rb', line 4003

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.



4013
4014
4015
4016
4017
4018
4019
4020
# File 'lib/HDLRuby/hruby_low.rb', line 4013

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.



4025
4026
4027
4028
4029
4030
4031
4032
# File 'lib/HDLRuby/hruby_low.rb', line 4025

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.



3988
3989
3990
3991
3992
3993
3994
3995
# File 'lib/HDLRuby/hruby_low.rb', line 3988

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.



208
209
210
211
212
213
214
215
216
217
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 208

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.



3998
3999
4000
# File 'lib/HDLRuby/hruby_low.rb', line 3998

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

#to_c(level = 0) ⇒ Object

Generates the C text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.



1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
# File 'lib/HDLRuby/hruby_low2c.rb', line 1499

def to_c(level = 0)
    res = "({\n"
    # Overrides the upper src0 and dst...
    res << (" " * ((level+1)*3))
    res << "Value src0, dst = get_value();\n"
    # Save the state of the value pool.
    res << (" " * ((level+1)*3))
    res << "unsigned int pool_state = get_value_pos();\n"
    # Compute the child.
    res << (" " * ((level+1)*3))
    res << "src0 = #{self.child.to_c(level+2)};\n"
    res << (" " * ((level+1)*3))
    res += "dst = cast_value(src0," +
        "#{self.type.to_c(level+1)},dst);\n"
    # Restore the value pool state.
    res << (" " * ((level+1)*3))
    res << "set_value_pos(pool_state);\n"
    # Close the computation
    res << (" " * (level*3))
    res << "dst; })"

    return res
end

#to_high(level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.



567
568
569
570
# File 'lib/HDLRuby/hruby_low2high.rb', line 567

def to_high(level = 0)
    return self.child.to_high(level) + 
        ".as(" + self.type.to_high(level) + ")"
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.



1610
1611
1612
1613
1614
1615
1616
1617
# File 'lib/HDLRuby/hruby_verilog.rb', line 1610

def to_verilog
    # return "#{self.type.to_verilog}'(#{self.child.to_verilog})"
    if self.type.signed? then
        return "$signed(#{self.child.to_verilog})"
    else
        return "$unsigned(#{self.child.to_verilog})"
    end
end

#to_vhdl(level = 0) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object.



1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1180

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



4035
4036
4037
4038
# File 'lib/HDLRuby/hruby_low.rb', line 4035

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