class HDLRuby::Low::Connection

Describes a connection.

NOTE: eventhough a connection is semantically different from a transmission, it has a common structure. Therefore, it is described as a subclass of a transmit.

Describes a connection.

NOTE: eventhough a connection is semantically different from a transmission, it has a common structure. Therefore, it is described as a subclass of a transmit.

Extends the Connection class with generation of C text.

Extends the Connection class with generation of hdr text.

Add the conversion to high.

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

Extends the Connection class with fixing of types and constants.

Describes a connection.

NOTE: eventhough a connection is semantically different from a transmission, it has a common structure. Therefore, it is described as a subclass of a transmit.

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

Translate expression of combination circuit. Enhance Connection with generation of verilog code.

Public Instance Methods

array_connection(left,right) click to toggle source

Method used for array.

# File lib/HDLRuby/hruby_verilog.rb, line 1566
def array_connection(left,right)
    expression = right.each_expression.to_a
    result = ""
    expression[0..-2].each do |expression|
        result << "   assign #{left.to_verilog}[#{expression.content.to_s}] = #{expression.to_verilog};\n"
    end
    result << "   assign #{left.to_verilog}[#{expression.last.content.to_s}] = #{expression.last.to_verilog};\n"
    return result
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 225
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_scope = self.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)
            # Set a default value to avoid latch generation.
            block.insert_statement!(0,
                    Transmit.new(aux.clone,Value.new(aux.type,0)))
            # 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
eql?(obj) click to toggle source

Comparison for hash: structural comparison.

Calls superclass method
# File lib/HDLRuby/hruby_low.rb, line 4282
def eql?(obj)
    return false unless obj.is_a?(Connection)
    return super(obj)
end
hash() click to toggle source

Hash function.

Calls superclass method
# File lib/HDLRuby/hruby_low.rb, line 4288
def hash
    return super
end
parent_system() click to toggle source

Gets the parent system, i.e., the parent of the top scope.

# File lib/HDLRuby/hruby_low.rb, line 4303
def parent_system
    return self.top_scope.parent
end
reassign_expressions!(node2reassign) click to toggle source

Replace node by corresponding replacement from node2reassign that is a table whose entries are: node the node to replace rep the replacement of the node ref the reference where to reassign the node.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1294
def reassign_expressions!(node2reassign)
    # Build the replacement table.
    node2rep = node2reassign.map {|n,r| [n,r[0]] }.to_h

    # Performs the replacements.
    node2rep_done = {} # The performed replacements.
    # Replace on the sons of the left.
    node2rep_done.merge!(self.left.replace_expressions!(node2rep))
    # Replace on the sons of the left.
    node2rep_done.merge!(self.right.replace_expressions!(node2rep))
    # Shall we replace 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)
        node2rep_done[node] = rep
    end

    # Assign the replaced nodes.
    node2rep_done.each do |node,rep|
        reassign = node2reassign[node][1].clone
        self.parent.add_connection(
            Connection.new(reassign,node.clone))
    end
end
to_high() click to toggle source

Creates a new high connection.

# File lib/HDLRuby/hruby_low2high.rb, line 364
def to_high
    return HDLRuby::High::Connection.new(self.left.to_high,
                                         self.right.to_high)
end
to_verilog() click to toggle source
# File lib/HDLRuby/hruby_verilog.rb, line 1576
def to_verilog
    # Decide whether to assign to array by if.
    # NOTICE: Now array assignment is done trough constant initialization, will be treated later.
    # if self.right.respond_to? (:each_expression)
    #   array_connection(self.left,self.right);
    # else
    cnt = 0  # Use count.
    bit = -2 # Used to determine the bit width. Since there are 0 and default, -2.

    # Measure the number of choices on the right side (case statement if it is 3 or more).
    if self.right.respond_to? (:each_choice)
        choice = self.right.each_choice.to_a
        choice.each do |choice|
            bit += 1
        end
    end

    # Three or more choices.
    if (bit > 2)
        # The bit width is obtained by converting the bit into a binary number and obtaining the size.
        bit = bit.to_s(2).size

        # Create a case statement.
        result = "   begin\n"
        result << "      case(#{self.right.select.to_verilog})\n"
        # Output other than the last one in order.
        choice[0..-2].each do |choice|
            result << "         #{bit}'#{cnt}: #{self.left.to_verilog} = #{choice.to_verilog}\n"
            cnt += 1
        end
        # At the end, it becomes default because it needs default.
        result << "         default: #{self.left.to_verilog} = #{choice.last.to_verilog}\n"
        result << "      endcase\n"
        result << "   end\n"
        return result
    end

    # It is not a case so call it normally.
    return "   assign #{self.left.to_verilog} = #{self.right.to_verilog};\n"
    # end
end
top_block() click to toggle source

Gets the top block, i.e. the first block of the current behavior.

# File lib/HDLRuby/hruby_low.rb, line 4293
def top_block
    raise AnyError, "Connections are not within blocks."
end
top_scope() click to toggle source

Gets the top scope, i.e. the first scope of the current system.

# File lib/HDLRuby/hruby_low.rb, line 4298
def top_scope
    return self.parent.is_a?(Scope) ? self.parent : self.parent.top_scope
end