class HDLRuby::Low::Transmit

Decribes a transmission statement.

Decribes a transmission statement.

Extends the Transmit class with generation of C text.

Extends the Transmit class with generation of hdr text.

Add the conversion to high.

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

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

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

Extends the Transmit class with fixing of types and constants.

Decribes a transmission statement.

Extends the Transmit class with functionality for breaking assingments to concats.

Extends the Transmit class with functionality for converting select expressions to case statements.

class of Represent blocking substitution or nonblocking assignment. Enhance Transmit with generation of verilog code.

Attributes

left[R]

The left reference.

right[R]

The right expression.

Public Class Methods

new(left,right) click to toggle source

Creates a new transmission from a right expression to a left reference.

Calls superclass method
# File lib/HDLRuby/hruby_low.rb, line 2933
def initialize(left,right)
    # Check and set the left reference.
    unless left.is_a?(Ref)
        raise AnyError,
             "Invalid class for a reference (left value): #{left.class}"
    end
    super()
    @left = left
    # and set its parent.
    left.parent = self
    # Check and set the right expression.
    unless right.is_a?(Expression)
        raise AnyError, "Invalid class for an expression (right value): #{right.class}"
    end
    @right = right
    # and set its parent.
    right.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 56
def boolean_in_assign2select!
    # Apply on the left value.
    self.set_left!(self.left.boolean_in_assign2select)
    # Apply on the right value.
    self.set_right!(self.right.boolean_in_assign2select)
    return self
end
break_concat_assigns() click to toggle source

Break the assignments to concats.

NOTE: when breaking generates a new Block containing the broken

assignments.
# File lib/HDLRuby/hruby_low_without_concat.rb, line 133
def break_concat_assigns
    # puts "break_concat_assigns with self=#{self}"
    # Is the left value a RefConcat?
    self.left.each_node_deep do |node|
        if node.is_a?(RefConcat) then
            # Yes, must break. Create the resulting sequential
            # block that will contain the new assignements.
            block = Block.new(:seq)
            # Create an intermediate signal for storing the
            # right value. Put it in the top scope.
            top_block = self.top_block
            top_scope = top_block.top_scope
            aux = top_scope.add_inner(
                SignalI.new(HDLRuby.uniq_name,self.right.type) )
            # puts "new signal: #{aux.name}"
            aux = RefName.new(aux.type,RefThis.new,aux.name)
            # Is a default value required to avoid latch generation?
            unless top_block.parent.each_event.
                    find {|ev| ev.type!=:change} then
                # Yes, generate it.
                top_block.insert_statement!(0,
                    Transmit.new(aux.clone,Value.new(aux.type,0)))
            end
            # Replace the concat in the copy of the left value.
            if left.eql?(node) then
                # node was the top of left, replace here.
                nleft = aux
            else
                # node was inside left, replace within left.
                nleft = self.left.clone
                nleft.each_node_deep do |ref|
                    ref.map_nodes! do |sub|
                        sub.eql?(node) ? aux.clone : sub
                    end
                end
            end
            # Recreate the transmit and add it to the block.
            block.add_statement(
                Transmit.new(nleft,self.right.clone) )
            # And assign its part to each reference of the
            # concat.
            pos = 0
            node.each_ref.reverse_each do |ref|
                # Compute the range to assign.
                range = ref.type.width-1+pos .. pos
                # Single or multi-bit range?
                sbit = range.first == range.last
                # Convert the range to an HDLRuby range for
                # using is the resulting statement.
                # Create and add the statement.
                if sbit then
                    # Single bit.
                    # Generate the index.
                    idx = Value.new(Integer,range.first)
                    # Generate the assignment.
                    block.add_statement(
                        Transmit.new(ref.clone,
                        # RefIndex.new(aux.type.base, aux.clone, idx)))
                        RefIndex.new(bit, aux.clone, idx)))
                else
                    # Multi-bits.
                    # Compute the type of the right value.
                    # rtype = TypeVector.new(:"",aux.type.base,range)
                    rtype = TypeVector.new(:"",bit,range)
                    # Generate the range.
                    range = Value.new(Integer,range.first) ..
                            Value.new(Integer,range.last)
                    # Generate the assignment.
                    block.add_statement(
                        Transmit.new(ref.clone,
                        RefRange.new(rtype, aux.clone, range)))
                end
                pos += ref.type.width
            end
            # puts "Resulting block=#{block.to_vhdl}"
            # Return the resulting block
            return block
        end
    end
    # No, nothing to do.
    return self
end
casts_without_expression!() click to toggle source

Extracts the expressions from the casts.

# File lib/HDLRuby/hruby_low_casts_without_expression.rb, line 57
def casts_without_expression!
    # Apply on the left value.
    self.set_left!(self.left.casts_without_expression)
    # Apply on the right value.
    self.set_right!(self.right.casts_without_expression)
    return self
end
clone() click to toggle source

Clones the transmit (deeply)

# File lib/HDLRuby/hruby_low.rb, line 2980
def clone
    return Transmit.new(@left.clone, @right.clone)
end
each_block(&ruby_block) click to toggle source

Iterates over the sub blocks.

# File lib/HDLRuby/hruby_low.rb, line 3016
def each_block(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_block) unless ruby_block
    # A ruby block?
    # Nothing to do.
end
each_block_deep(&ruby_block) click to toggle source

Iterates over all the blocks contained in the current block.

# File lib/HDLRuby/hruby_low.rb, line 3024
def each_block_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_block_deep) unless ruby_block
    # A ruby block?
    # Nothing to do.
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 2955
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 left.
    self.left.each_deep(&ruby_block)
    # Then apply on the right.
    self.right.each_deep(&ruby_block)
end
each_expression(&ruby_block)
Alias for: each_node
each_node(&ruby_block) click to toggle source

Iterates over the children if any.

# File lib/HDLRuby/hruby_low.rb, line 2985
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 children.
    ruby_block.call(@left)
    ruby_block.call(@right)
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 2996
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 children
    @left.each_node_deep(&ruby_block)
    @right.each_node_deep(&ruby_block)
end
each_statement_deep(&ruby_block) click to toggle source

Iterates over all the stamements of the block and its sub blocks.

# File lib/HDLRuby/hruby_low.rb, line 3007
def each_statement_deep(&ruby_block)
    # No ruby statement? Return an enumerator.
    return to_enum(:each_statement_deep) unless ruby_block
    # A ruby block?
    # Apply it on self.
    ruby_block.call(self)
end
eql?(obj) click to toggle source

Comparison for hash: structural comparison.

# File lib/HDLRuby/hruby_low.rb, line 2967
def eql?(obj)
    return false unless obj.is_a?(Transmit)
    return false unless @left.eql?(obj.left)
    return false unless @right.eql?(obj.right)
    return true
end
explicit_types!() click to toggle source

Explicit the types conversions in the statement.

# File lib/HDLRuby/hruby_low_fix_types.rb, line 82
def explicit_types!
    # Recurse on the left and the right.
    self.set_left!(self.left.explicit_types)
    # The right have to match the left type.
    self.set_right!(self.right.explicit_types(self.left.type))
    return self
end
extract_selects!() click to toggle source

Extract the Select expressions.

# File lib/HDLRuby/hruby_low_without_select.rb, line 158
def extract_selects!
    selects = []
    self.set_left!(self.left.extract_selects_to!(selects))
    self.set_right!(self.right.extract_selects_to!(selects))
    return selects
end
hash() click to toggle source

Hash function.

# File lib/HDLRuby/hruby_low.rb, line 2975
def hash
    return [@left,@right].hash
end
map_nodes!(&ruby_block) click to toggle source

Maps on the children.

# File lib/HDLRuby/hruby_low_mutable.rb, line 584
def map_nodes!(&ruby_block)
    @left = ruby_block.call(@left)
    left.parent = self unless left.parent
    @right = ruby_block.call(@right)
    right.parent = self unless right.parent
end
replace_expressions!(node2rep) click to toggle source

Replaces sub expressions using node2rep table indicating the node to replace and the corresponding replacement. Returns the actually replaced nodes and their corresponding replacement.

NOTE: the replacement is duplicated.

# File lib/HDLRuby/hruby_low_mutable.rb, line 597
def replace_expressions!(node2rep)
    # First recurse on the children.
    res = self.left.replace_expressions!(node2rep)
    res.merge!(self.right.replace_expressions!(node2rep))
    # Is there a replacement to do on the left?
    rep = node2rep[self.left]
    if rep then
        # Yes, do it.
        rep = rep.clone
        node = self.left
        # node.set_parent!(nil)
        self.set_left!(rep)
        # And register the replacement.
        res[node] = rep
    end
    # Is there a replacement to do on the right?
    rep = node2rep[self.right]
    if rep then
        # Yes, do it.
        rep = rep.clone
        node = self.right
        # node.set_parent!(nil)
        self.set_right!(rep)
        # And register the replacement.
        res[node] = rep
    end

    return res
end
set_left!(left) click to toggle source

Sets the left.

# File lib/HDLRuby/hruby_low_mutable.rb, line 561
def set_left!(left)
    # Check and set the left reference.
    unless left.is_a?(Ref)
        raise AnyError,
             "Invalid class for a reference (left value): #{left.class}"
    end
    @left = left
    # and set its parent.
    left.parent = self
end
set_right!(right) click to toggle source

Sets the right.

# File lib/HDLRuby/hruby_low_mutable.rb, line 573
def set_right!(right)
    # Check and set the right expression.
    unless right.is_a?(Expression)
        raise AnyError, "Invalid class for an expression (right value): #{right.class}"
    end
    @right = right
    # and set its parent.
    right.parent = self
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 1096
def to_c(level = 0)
    # Save the state of the value pool.
    res = (" " * ((level)*3))
    res << "{\n"
    res << (" " * ((level+1)*3))
    res << "unsigned int pool_state = get_value_pos();\n"
    # Perform the copy and the touching only if the new content
    # is different.
    res << (" " * ((level+1)*3))
    # Is it a sequential execution model?
    seq = self.block.mode == :seq ? "_seq" : ""
    # Generate the assignment.
    if (self.left.is_a?(RefName)) then
        # Direct assignment to a signal, simple transmission.
        res << "transmit_to_signal#{seq}(#{self.right.to_c(level)},"+
            "#{self.left.to_c_signal(level)});\n"
    else
        # Assignment inside a signal (RefIndex or RefRange).
        res << "transmit_to_signal_range#{seq}(#{self.right.to_c(level)},"+
            "#{self.left.to_c_signal(level)});\n"
    end
    # Restore the value pool state.
    res << (" " * ((level+1)*3))
    res << "set_value_pos(pool_state);\n"
    res << (" " * ((level)*3))
    res << "}\n"
    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 338
def to_hdr(level = 0)
    return " " * (level*3) + 
           self.left.to_hdr(level) + " <= " +
           self.right.to_hdr(level) + "\n"
end
to_high() click to toggle source

Creates a new high transmit statement.

# File lib/HDLRuby/hruby_low2high.rb, line 242
def to_high
    return HDLRuby::High::Transmit.new(self.left.to_high,
                                       self.right.to_high)
end
to_verilog(spc = 3) click to toggle source

Converts the system to Verilog code.

# File lib/HDLRuby/hruby_verilog.rb, line 108
def to_verilog(spc = 3)
    # Determine blocking assignment or nonblocking substitution from mode and return it.
    code = "#{" " * spc}#{self.left.to_verilog} #{self.block.mode == :seq ? "=" : "<="} #{self.right.to_verilog};"
    return code
end
to_vhdl(vars,level = 0) click to toggle source

Generates the text of the equivalent HDLRuby::High code. vars is the list of the variables and level is the hierachical level of the object.

# File lib/HDLRuby/hruby_low2vhd.rb, line 903
def to_vhdl(vars,level = 0)
    # Generate the assign operator.
    assign = vars.any? do |var|
        self.left.respond_to?(:name) && var.name == self.left.name 
    end ? " := " : " <= "
    # Generate the assignment.
    return " " * (level*3) + 
           self.left.to_vhdl(level) + assign +
           Low2VHDL.to_type(self.left.type,self.right) + ";\n"
end
use_name?(*names) click to toggle source

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

# File lib/HDLRuby/hruby_low.rb, line 3032
def use_name?(*names)
    return @left.use_name?(*names) || @right.use_name?(*names)
end