Class: HDLRuby::Low::Unary

Inherits:
Operation show all
Includes:
OneChildMutable
Defined in:
lib/HDLRuby/hruby_db.rb,
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_with_bool.rb,
lib/HDLRuby/hruby_low_bool2select.rb,
lib/HDLRuby/hruby_low_casts_without_expression.rb

Overview

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

Direct Known Subclasses

High::Unary

Constant Summary

Constants included from Low2Symbol

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

Instance Attribute Summary collapse

Attributes inherited from Operation

#operator

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 Operation

#set_operator!

Methods inherited from Expression

#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, operator, child) ⇒ Unary

Creates a new unary expression with +type+ applying +operator+ on +child+ expression. def initialize(operator,child)



4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
# File 'lib/HDLRuby/hruby_low.rb', line 4100

def initialize(type,operator,child)
    # Initialize as a general operation.
    super(type,operator)
    # 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.



4095
4096
4097
# File 'lib/HDLRuby/hruby_low.rb', line 4095

def child
  @child
end

Instance Method Details

#boolean?Boolean

Tells if the expression is boolean.

Returns:

  • (Boolean)


107
108
109
# File 'lib/HDLRuby/hruby_low_with_bool.rb', line 107

def boolean?
    return self.child.boolean?
end

#boolean_in_assign2selectObject

Converts booleans in assignments to select operators.



183
184
185
186
187
188
# File 'lib/HDLRuby/hruby_low_bool2select.rb', line 183

def boolean_in_assign2select
    # Recurse on the sub node.
    return Unary.new(self.type,self.operator,
                     self.child.boolean_in_assign2select)
    return self
end

#casts_without_expressionObject

Extracts the expressions from the casts.



210
211
212
213
214
215
# File 'lib/HDLRuby/hruby_low_casts_without_expression.rb', line 210

def casts_without_expression
    # Recurse on the sub node.
    return Unary.new(self.type,self.operator,
                     self.child.casts_without_expression)
    return self
end

#cloneObject

Clones the unary operator (deeply)



4167
4168
4169
# File 'lib/HDLRuby/hruby_low.rb', line 4167

def clone
    return Unary.new(@type,self.operator,@child.clone)
end

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

Iterates over the expression children if any.



4129
4130
4131
4132
4133
4134
# File 'lib/HDLRuby/hruby_low.rb', line 4129

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.



4139
4140
4141
4142
4143
4144
4145
4146
# File 'lib/HDLRuby/hruby_low.rb', line 4139

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.



4151
4152
4153
4154
4155
4156
4157
4158
# File 'lib/HDLRuby/hruby_low.rb', line 4151

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)


4114
4115
4116
4117
4118
4119
4120
4121
# File 'lib/HDLRuby/hruby_low.rb', line 4114

def eql?(obj)
    # General comparison.
    return false unless super(obj)
    # Specific comparison.
    return false unless obj.is_a?(Unary)
    return false unless @child.eql?(obj.child)
    return true
end

#explicit_types(type = nil) ⇒ Object

Explicit the types conversions in the unary operation where +type+ is the expected type of the condition if any.



235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/HDLRuby/hruby_low_fix_types.rb', line 235

def explicit_types(type = nil)
    # Recurse on the child (no type to specify here, unary operations
    # preserve the type of their child).
    op = Unary.new(self.type,self.operator,self.child.explicit_types)
    # Does the type match the operation?
    if type && !self.type.eql?(type) then
        # No create a cast.
        return Cast.new(type,op)
    else
        # Yes, return the operation as is.
        return op
    end
end

#hashObject

Hash function.



4124
4125
4126
# File 'lib/HDLRuby/hruby_low.rb', line 4124

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.



1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
# File 'lib/HDLRuby/hruby_low2c.rb', line 1541

def to_c(level = 0)
    res = "({\n"
    # Overrides the upper src0 and dst...
    res << (" " * ((level+1)*3))
    res << "Value src0, dst;\n"
    if (self.operator != :+@) then
        # And allocates a new value for dst unless the operator
        # is +@ that does not compute anything.
        res << (" " * ((level+1)*3))
        res << "dst = get_value();\n"
    end
    # 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))
    case self.operator
    when :~ then
        res += "dst = not_value(src0,dst);\n"
    when :-@ then
        res += "dst = neg_value(src0,dst);\n"
    when :+@ then
        res += "dst = #{self.child.to_c(level)};\n"
    else
        raise "Invalid unary operator: #{self.operator}."
    end
    # 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.



589
590
591
# File 'lib/HDLRuby/hruby_low2high.rb', line 589

def to_high(level = 0)
    return "(#{self.operator.to_s[0]}" + self.child.to_high(level) + ")"
end

#to_verilogObject

Converts the system to Verilog code.



1608
1609
1610
# File 'lib/HDLRuby/hruby_verilog.rb', line 1608

def to_verilog
    return "#{self.operator[0]}#{self.child.to_verilog}"
end

#to_vhdl(level = 0, std_logic = false) ⇒ Object

Generates the text of the equivalent HDLRuby::High code. +level+ is the hierachical level of the object. +std_logic+ tells if std_logic computation is to be done.



1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
# File 'lib/HDLRuby/hruby_low2vhd.rb', line 1224

def to_vhdl(level = 0, std_logic = false)
    # Generate the operator string.
    operator = self.operator == :~ ? "not " : self.operator.to_s[0]
    # Is the operator arithmetic?
    if [:+@, :-@].include?(self.operator) then
        # Yes, type conversion my be required by VHDL standard.
        res = "#{Low2VHDL.unarith_cast(self)}(#{operator}" +
                     Low2VHDL.to_arith(self.child) + ")"
        res += "(0)" if std_logic
        return res
    else
        # No, generate simply the unary operation.
        # (The other unary operator is logic, no need to force
        # std_logic.)
        return "(#{operator}" + self.child.to_vhdl(level,std_logic) + ")"
    end
end

#use_name?(*names) ⇒ Boolean

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

Returns:

  • (Boolean)


4161
4162
4163
4164
# File 'lib/HDLRuby/hruby_low.rb', line 4161

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