class HDLRuby::Low::Cast

Describes a cast.

Extends the Cast class with generation of C text.

Extends the Cast class with generation of hdr text.

Add the conversion to high.

Extends the Cast class with generation of HDLRuby::High text.

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

Extends the Cast class with functionality for extracting expressions from cast.

Extends the Cast class with fixing of types and constants.

Describes a cast.

Used when casting expressions.

Attributes

child[R]

The child

Public Class Methods

new(type,child) click to toggle source

Creates a new cast of child to type.

Calls superclass method HDLRuby::Low::Expression::new
# File lib/HDLRuby/hruby_low.rb, line 4538
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

Public Instance Methods

boolean_in_assign2select() click to toggle source

Converts booleans in assignments to select operators.

# File lib/HDLRuby/hruby_low_bool2select.rb, line 186
def boolean_in_assign2select
    # Recurse on the child.
    return Cast.new(self.type,self.child.boolean_in_assign2select)
end
casts_without_expression() click to toggle source

Extracts the expressions from the casts.

# File lib/HDLRuby/hruby_low_casts_without_expression.rb, line 183
def casts_without_expression
    # Recurse on the child.
    nchild = self.child.casts_without_expression
    # 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() click to toggle source

Clones the value (deeply)

# File lib/HDLRuby/hruby_low.rb, line 4624
def clone
    return Cast.new(@type,@child.clone)
end
each_deep(&ruby_block) click to toggle source

Iterates over each object deeply.

Returns an enumerator if no ruby block is given.

# File lib/HDLRuby/hruby_low.rb, line 4559
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_expression(&ruby_block)
Alias for: each_node
each_node(&ruby_block) click to toggle source

Iterates over the expression children if any.

# File lib/HDLRuby/hruby_low.rb, line 4586
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
Also aliased as: each_expression
each_node_deep(&ruby_block) click to toggle source

Iterates over the nodes deeply if any.

# File lib/HDLRuby/hruby_low.rb, line 4596
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) click to toggle source

Iterates over all the references encountered in the expression.

NOTE: do not iterate inside the references.

# File lib/HDLRuby/hruby_low.rb, line 4608
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) click to toggle source

Comparison for hash: structural comparison.

Calls superclass method HDLRuby::Low::Expression#eql?
# File lib/HDLRuby/hruby_low.rb, line 4571
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) click to toggle source

Explicit the types conversions in the cast where type is the expected type of the condition if any.

# File lib/HDLRuby/hruby_low_fix_types.rb, line 222
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() click to toggle source

Hash function.

Calls superclass method HDLRuby::Low::Expression#hash
# File lib/HDLRuby/hruby_low.rb, line 4581
def hash
    return [super,@child].hash
end
immutable?() click to toggle source

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

# File lib/HDLRuby/hruby_low.rb, line 4551
def immutable?
    # Immutable if the child is immutable.
    return child.immutable?
end
to_c(level = 0) click to toggle source

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

# File lib/HDLRuby/hruby_low2c.rb, line 1612
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_hdr(level = 0) click to toggle source

Generates the text of the equivalent hdr text. level is the hierachical level of the object.

# 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() click to toggle source

Creates a new high cast expression.

# 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() click to toggle source

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

by traditional verilog.
# File lib/HDLRuby/hruby_verilog.rb, line 1639
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])"
        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])"
        else
            # Only enforce signed.
            return "$unsigned(#{self.child.to_verilog})"
        end
    end
end
to_vhdl(level = 0) click to toggle source

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

# File lib/HDLRuby/hruby_low2vhd.rb, line 1204
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) click to toggle source

Tell if the expression includes a signal whose name is one of names.

# File lib/HDLRuby/hruby_low.rb, line 4618
def use_name?(*names)
    # Recurse on the child.
    return @child.use_name?(*names)
end