class HDLRuby::Low::Block

Describes a block.

Describes a block.

Extends the Block class with generation of C text.

Extends the Block class with generation of hdr text.

Add the conversion to high.

Extends the Block class with functionality for converting par block to seq.

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

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

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

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

Extends the Block class with fixing of types and constants.

Describes a block.

Extends Block with the capability of finding one of its inner object by name.

Extends the Block class with separation between signals and variables.

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

Extends the When class with functionality for moving the declarations to the upper namespace.

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

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

To scheduling to the Block. Enhance Block with generation of verilog code.

Attributes

mode[R]

The execution mode of the block.

name[R]

The name of the block if any

Public Class Methods

new(mode, name = :"") click to toggle source

Creates a new mode sort of block with possible name.

Calls superclass method
# File lib/HDLRuby/hruby_low.rb, line 3991
def initialize(mode, name = :"")
    super()
    # puts "new block with mode=#{mode} and name=#{name}"
    # Check and set the type.
    @mode = mode.to_sym
    # Check and set the name.
    @name = name.to_sym
    # Initializes the list of inner statements.
    # @inners = {}
    @inners = HashName.new
    # Initializes the list of statements.
    @statements = []
end

Public Instance Methods

add_blocks_code(res,level) click to toggle source

Adds the c code of the blocks to res at level

# File lib/HDLRuby/hruby_low2c.rb, line 1366
def add_blocks_code(res,level)
    res << self.to_c_code(level)
end
add_inner(signal) click to toggle source

Adds inner signal signal.

# File lib/HDLRuby/hruby_low.rb, line 4049
def add_inner(signal)
    # Check and add the signal.
    unless signal.is_a?(SignalI)
        raise AnyError,
              "Invalid class for a signal instance: #{signal.class}"
    end
    # if @inners.has_key?(signal.name) then
    if @inners.include?(signal) then
        raise AnyError, "SignalI #{signal.name} already present."
    end
    # @inners[signal.name] = signal
    # Set its parent.
    signal.parent = self
    # And add it
    @inners.add(signal)
end
add_make_block(res,level) click to toggle source

Adds the creation of the blocks to res at level.

# File lib/HDLRuby/hruby_low2c.rb, line 1371
def add_make_block(res,level)
    res << " " * level*3
    res << "#{Low2C.make_name(self)}();\n"
end
add_statement(statement) click to toggle source

Adds a statement.

NOTE: TimeWait is not supported unless for TimeBlock objects.

# File lib/HDLRuby/hruby_low.rb, line 4099
def add_statement(statement)
    unless statement.is_a?(Statement) then
        raise AnyError,
              "Invalid class for a statement: #{statement.class}"
    end
    if statement.is_a?(TimeWait) then
        raise AnyError,
              "Timed statements are not supported in common blocks."
    end
    @statements << statement
    # And set its parent.
    statement.parent = self
    statement
end
add_variable(name,type) click to toggle source

Adds variable name with type.

# File lib/HDLRuby/hruby_low_with_var.rb, line 137
def add_variable(name,type)
    # Ensure name is a symbol.
    name = name.to_sym
    # Declares the variable as an inner.
    inner = add_inner(SignalI.new(name,type))
    # And register it as a variable.
    variables[name] = inner 
end
att_sharp(left,att = "'") click to toggle source

A method that takes a variable from the sent left side and adds “att”.

# File lib/HDLRuby/hruby_verilog.rb, line 1331
def att_sharp(left,att = "'")
    new_left = search_refname(left, att)

    return new_left
end
att_signal(left,att = "'") click to toggle source

Generate a signal for the variable to which “'” or “#” is added.

# File lib/HDLRuby/hruby_verilog.rb, line 1322
def att_signal(left,att = "'")
    this_name = res_name(left)
    new_name = RefName.new(this_name.type, this_name.ref.clone, this_name.name.to_s + att)
    new_signal = SignalI.new(new_name.name,new_name.type)

    return new_signal
end
blocks2seq!() click to toggle source

Converts the par sub blocks to seq.

# File lib/HDLRuby/hruby_low2seq.rb, line 198
def blocks2seq!
    # First recurse on each statement.
    self.each_statement { |stmnt| stmnt.blocks2seq! }
    # If the block is already seq, nothing more to do.
    return self if self.mode == :seq
    # IF the block contains one or less transmit statement,
    # simply change its mode.
    if self.each_statement.count { |stmnt| stmnt.is_a?(Transmit) } <= 1
        self.set_mode!(:par)
        return self
    end
    # Gather the left values of the assignments.
    lvalues = self.each_statement.select do |stmnt|
        stmnt.is_a?(Transmit)
    end.map { |trans| trans.left }
    # Gather the right values inside the whole block.
    rvalues = self.each_node_deep.select do |node|
        node.is_a?(Expression) and node.rightvalue?
    end
    # Keep the left value that are reused.
    lvalues = lvalues & rvalues
    # Create new inner variable for replacing them.
    nvalues = []
    lvalues.each do |lvalue|
        # Create the replacing variable.
        nvalues << nvalue = self.add_inner(
            SignalI.new(HDLRuby.uniq_name,lvalue.type))
        # Replace it.
        ref = RefName.new(lvalue.type, RefThis.new, nvalues[-1].name)
        lvalue.parent.set_left!(ref)
        # And reassign it at the end of the block.
        lvalue.parent = nil
        assign = Transmit.new(lvalue,ref.clone)
        self.add_statement(assign)
    end
    return self
end
boolean_in_assign2select!() click to toggle source

Converts booleans in assignments to select operators.

# File lib/HDLRuby/hruby_low_bool2select.rb, line 163
def boolean_in_assign2select!
    # Apply on each statement.
    self.each_statement(&:boolean_in_assign2select!)
    return self
end
break_concat_assigns!() click to toggle source

Breaks the assignments to concats.

NOTE: work on the direct sub statement only, not deeply.

# File lib/HDLRuby/hruby_low_without_concat.rb, line 109
def break_concat_assigns!
    # Check each transmit.
    self.each_statement.each.with_index do |stmnt,i|
        if stmnt.is_a?(Transmit) then
            # Transmit, breaking may be necessary.
            nstmnt = stmnt.break_concat_assigns
            if nstmnt.is_a?(Block) then
                # The transmit has been broken, remove the former
                # version and add the generated block as a behavior.
                self.set_statement!(i,nstmnt)
            end
        end
    end
end
casts_without_expression!() click to toggle source

Extracts the expressions from the casts.

# File lib/HDLRuby/hruby_low_casts_without_expression.rb, line 160
def casts_without_expression!
    # Apply on each statement.
    self.each_statement(&:casts_without_expression!)
    return self
end
change_branch(block) click to toggle source
# File lib/HDLRuby/hruby_verilog.rb, line 1231
def change_branch(block)
    flat  = Block.new(self.mode,"")     # Store the expression until if is found.
    trans = Block.new(self.mode,"")     # A block that stores the expression after if is found.
    new_block = Block.new(self.mode,"") # Block storing each converted expression.

    has_branch = false                  # It is true if there is an if in the block.
    more_has_branch = false             # It is true if there are two or more if in the block.

    # Search each expression for if.
    block.each_statement do |statement|
        if (has_branch)
            trans.add_statement(statement.clone)
            if statement.is_a?(If) || statement.is_a?(Case) then
                more_has_branch = true
            end        
        else
            if statement.is_a?(If) || statement.is_a?(Case) then
                flat.add_statement(statement.clone)     
                has_branch = true          
            else
                flat.add_statement(statement.clone)
            end
        end
    end

    # If there are two or more if, recursively process if.
    if(more_has_branch) then
        conversion_block = change_branch(trans)
    else
        conversion_block = trans.clone
    end

    # Store "trans" contents for "if" and "case" in "flat".
    flat.each_statement do |statement|
        # Since case statements include defaulu and when, we store the expressions saved in each case.
        if statement.is_a?(Case) then
            if statement.default.is_a?(Block)
                new_default = statement.default.clone 
                conversion_block.each_statement do |smt|
                    new_default.add_statement(smt.clone)
                end         
            end

            new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])

            statement.each_when do |whens|
                new_when = whens.clone

                conversion_block.each_statement do |smt|
                    new_when.statement.add_statement(smt.clone)
                end      
                new_statement.add_when(new_when.clone)
            end

            new_block.add_statement(new_statement.clone)
            # Because there are yes, no and noifs in the if statement, store the expression saved in each.
        elsif statement.is_a?(If) then
            new_yes = statement.yes.clone
            conversion_block.each_statement do |smt|
                new_yes.add_statement(smt.clone)
            end

            if statement.no.is_a? (Block) then
                new_no = statement.no.clone
                conversion_block.each_statement do |smt|
                    new_no.add_statement(smt.clone)
                end
            end

            # Make new if with converted yes and no.
            new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)


            statement.each_noif do |condition, block|
                new_noif = block.clone
                conversion_block.each_statement do |smt|
                    new_noif.add_statement(smt.clone)
                end
                new_statement.add_noif(condition.clone,new_noif.clone)
            end
            # Add the new statement (if) created to flat.
            new_block.add_statement(new_statement.clone)
        else
            new_block.add_statement(statement.clone)
        end
    end

    return new_block # Return block after conversion.
end
clone() click to toggle source

Clones (deeply)

# File lib/HDLRuby/hruby_low.rb, line 4215
def clone
    # Creates the new block.
    nblock = Block.new(self.mode,self.name)
    # Duplicate its content.
    self.each_statement do |statement|
        nblock.add_statement(statement.clone)
    end
    return nblock
end
delete_inner!(signal) click to toggle source

Deletes an inner.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1112
def delete_inner!(signal)
    if @inners.key?(signal.name) then
        # The signal is present, delete it.
        @inners.delete(signal.name)
        # And remove its parent.
        signal.parent = nil
    end
    signal
end
delete_statement!(statement) click to toggle source

Deletes a statement.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1178
def delete_statement!(statement)
    if @statements.include?(statement) then
        # Statement is present, delete it.
        @statements.delete(statement)
        # And remove its parent.
        statement.parent = nil
    end
    statement
end
delete_unless!(keep) click to toggle source

Removes the signals and corresponding assignments whose name is not in keep.

# File lib/HDLRuby/hruby_low_cleanup.rb, line 172
def delete_unless!(keep)
    # Delete the unecessary inner signals.
    self.each_inner.to_a.each do |inner|
        self.delete_inner!(inner) unless keep.include?(inner.name)
    end

    # Recurse on the sub statements.
    self.each_statement {|stmnt| stmnt.delete_unless!(keep) }

    # Delete the unecessary assignments.
    self.each_statement.to_a.each do |stmnt|
        if stmnt.is_a?(Transmit) &&
             !stmnt.left.each_node_deep.any? { |node| 
            node.is_a?(RefName) && keep.include?(node.name) } then
            self.delete_statement!(stmnt)
        end
    end
end
do_flat(mode = nil) click to toggle source
# File lib/HDLRuby/hruby_verilog.rb, line 706
def do_flat(mode = nil)
    flat  = Block.new(self.mode,"")   # Block between lower layers when converting.
    trans = Block.new(self.mode,"")   # The block used for converting itself.
    replase = Block.new(self.mode,"") # block to be used for further conversion in case of if statement.
    list = []
    rep_list = []

    # If there is a block inside the statement it is not the lowest layer. If there is, it is the lowest layer.
    if (self.each_statement.find {|stmnt| stmnt.is_a?(Block)} || (self.each_statement.find {|stmnt| stmnt.is_a?(If)}) || (self.each_statement.find {|stmnt| stmnt.is_a?(Case)}))then
        # In the case of seq, the lower layer is par. Isolate fm_par so that it is not crosstalked.
        if(self.mode == :seq) then
            fm_buckup = $fm.fm_par.clone
            $fm.fm_par.clear()

            new_block = change_branch(self)
        else
            new_block = self.clone      
        end

        # Process for each statement.
        new_block.each_statement do |statement|
            # If statement is If, convert yes, no, noif and add them to flat.
            if statement.is_a?(Case) then
                if(self.mode == :seq) then
                    fm_buckup_if = $fm.fm_par.clone
                end

                if statement.default.is_a?(Block)
                    default = statement.default.flatten    
                    new_default = Block.new(default.mode,"")

                    default.each_statement do |statement|
                        new_default.add_statement(statement.clone)
                    end     
                end


                new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])

                statement.each_when do |whens|
                    if(self.mode == :seq) then
                        fm_buckup_if.each_key do |key|
                            $fm.fm_par[key] = fm_buckup_if[key]
                        end
                    end

                    when_smt = whens.statement.flatten
                    new_when = When.new(whens.match.clone,when_smt.clone)
                    new_statement.add_when(new_when.clone)
                end
                flat.add_statement(new_statement)

            elsif statement.is_a?(If) then
                if(self.mode == :seq) then
                    fm_buckup_if = $fm.fm_par.clone
                end

                # Since yes always exist, convert without confirming.
                new_yes = statement.yes.flatten

                # I do not know whether no (else) exists, so convert it if it is confirmed.
                if statement.no.is_a? (Block) then

                    if(self.mode == :seq) then
                        fm_buckup_if.each_key do |key|
                            $fm.fm_par[key] = fm_buckup_if[key]
                        end
                    end

                    new_no = statement.no.flatten
                end
                # Create a new if statement with converted yes and no.
                new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)

                # Since I do not know whether there is noifs (elsif), I convert it and add it if it is confirmed.
                statement.each_noif do |condition, block|
                    if(self.mode == :seq) then
                        fm_buckup_if.each_key do |key|
                            $fm.fm_par[key] = fm_buckup_if[key]
                        end
                    end

                    new_noif = block.flatten         
                    new_statement.add_noif(condition.clone,new_noif.clone)
                end
                # Add the new statement (if statement) created to flat.
                flat.add_statement(new_statement.clone)

                # If statement is Transmit, record the expression in fm_par and add the expression to flat as it is.
            elsif statement.is_a?(Transmit) then
                if(self.mode == :seq) then
                    $fm.fm_par["#{statement.left.to_verilog}"] = statement.right.clone
                end

                flat.add_statement(statement.clone)
                # If statement is Block, convert it with do_flat and add the returned expression and variable to flat respectively.

            elsif statement.is_a?(Block) then
                smt = statement.do_flat(self.mode)
                # If smt has inner, check it separately and add it if it's convenient.
                smt.each_inner do |inner|
                    if self.mode == :seq then
                        unless (list.include?(inner.name.to_s)) then
                            list << inner.name.to_s
                            flat.add_inner(inner.clone)
                        end
                    else
                        unless (list.include?(inner.name.to_s)) then
                            if(inner.name.to_s.include? "#") then
                                list << inner.name.to_s
                                flat.add_inner(inner.clone) # It was new_block. why?
                            end
                        end            
                    end
                end
                # If it is seq, the expression after conversion is also likely to be used, so record the expression.
                smt.each_statement do |tmt|
                    if self.mode == :seq then
                        $fm.fm_par["#{tmt.left.to_verilog}"] = tmt.right.clone
                    end
                    flat.add_statement(tmt.clone)
                end         
            end
        end

        # Overwrite to restore fm_par which was quarantined.
        if(self.mode == :seq) then
            $fm.fm_par.clear()
            fm_buckup.each_key do |key|
                $fm.fm_par[key] = fm_buckup[key]
            end
        end



        # Since it is a middle tier itself, it performs flat transformation, shifts inner, and returns the result.
        trans = flat.to_conversion(mode)


        # Write an expression that assigns an identifier that added # to an identifier that has not added.
        trans.each_statement do |statement|
            replase.add_statement(statement.clone)
            if statement.is_a?(If)
                $fm.rep_sharp.each_key do |key|
                    new_statement = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
                    replase.add_statement(new_statement.clone)
                end
                $fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
            end
        end

        # Extract the inner left in flat and add it to replase.
        flat.each_inner do |inner|
            replase.add_inner(inner.clone)
        end

        # Extract the inner left in trans and add it to replase.
        trans.each_inner do |inner|
            replase.add_inner(inner.clone)
        end

        return replase

        # Processing when there is no block (reaching the bottom layer).
    else
        # Since it is the lowest layer, it does not smooth but converts itself and returns it.
        flat = self.to_conversion(mode)
        return flat
    end
end
each_block(&ruby_block) click to toggle source

Iterates over the sub blocks.

# File lib/HDLRuby/hruby_low.rb, line 4165
def each_block(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_block) unless ruby_block
    # A ruby block?
    # Apply it on each statement which contains blocks.
    self.each_statement do |statement|
        ruby_block.call(statement) if statement.is_a?(Block)
    end
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 4176
def each_block_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_block_deep) unless ruby_block
    # A ruby block?
    # Apply it on self.
    ruby_block.call(self)
    # And apply it on each statement which contains blocks.
    self.each_statement do |statement|
        statement.each_block_deep(&ruby_block)
    end
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 4008
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 inners.
    self.each_inner do |inner|
        inner.each_deep(&ruby_block)
    end
    # Then apply on the statements.
    self.each_statement do |stmnt|
        stmnt.each_deep(&ruby_block)
    end
end
each_inner(&ruby_block) click to toggle source

Iterates over the inner signals.

Returns an enumerator if no ruby block is given.

# File lib/HDLRuby/hruby_low.rb, line 4069
def each_inner(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_inner) unless ruby_block
    # A ruby block? Apply it on each inner signal instance.
    @inners.each(&ruby_block)
end
Also aliased as: each_signal
each_node(&ruby_block)
Alias for: each_statement
each_node_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 4202
def each_node_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_node_deep) unless ruby_block
    # A ruby block?
    # Apply it on current.
    ruby_block.call(self)
    # And apply it on each statement deeply.
    self.each_statement do |stmnt|
        stmnt.each_node_deep(&ruby_block)
    end
end
each_signal(&ruby_block)
Alias for: each_inner
each_signal_deep(&ruby_block) click to toggle source

Iterates over all the signals of the block and its sub block's ones.

# File lib/HDLRuby/hruby_low.rb, line 4084
def each_signal_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_signal_deep) unless ruby_block
    # A ruby block?
    # First, apply on the signals of the block.
    self.each_signal(&ruby_block)
    # Then apply on each sub block.
    self.each_block_deep do |block|
        block.each_signal_deep(&ruby_block)
    end
end
each_statement(&ruby_block) click to toggle source

Iterates over the statements.

Returns an enumerator if no ruby block is given.

# File lib/HDLRuby/hruby_low.rb, line 4140
def each_statement(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_statement) unless ruby_block
    # A ruby block? Apply it on each statement.
    @statements.each(&ruby_block)
end
Also aliased as: each_node
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 4189
def each_statement_deep(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_statement_deep) unless ruby_block
    # A ruby block?
    # Apply it on current.
    ruby_block.call(self)
    # And apply it on each statement deeply.
    self.each_statement do |statement|
        statement.each_statement_deep(&ruby_block)
    end
end
eql?(obj) click to toggle source

Comparison for hash: structural comparison.

# File lib/HDLRuby/hruby_low.rb, line 4024
def eql?(obj)
    return false unless obj.is_a?(Block)
    return false unless @mode.eql?(obj.mode)
    return false unless @name.eql?(obj.name)
    idx = 0
    obj.each_inner do |inner|
        return false unless @inners[inner.name].eql?(inner)
        idx += 1
    end
    return false unless idx == @inners.size
    idx = 0
    obj.each_statement do |statement|
        return false unless @statements[idx].eql?(statement)
        idx += 1
    end
    return false unless idx == @statements.size
    return true
end
explicit_types!() click to toggle source

Explicit the types conversions in the block.

# File lib/HDLRuby/hruby_low_fix_types.rb, line 177
def explicit_types!
    # Recurse on the statements.
    self.each_statement(&:explicit_types!)
    return self
end
extract_declares!() click to toggle source

Extract the declares from the scope and returns them into an array.

NOTE: do not recurse into the sub scopes or behaviors!

# File lib/HDLRuby/hruby_low_without_namespace.rb, line 686
def extract_declares!
    # Ensure there is a name.
    self.force_name!
    # The extracted declares.
    decls = []
    # Extract the inners.
    self.each_inner {|inner| decls << inner }
    decls.each {|inner| self.delete_inner!(inner) }
    # Renames them with the current level.
    decls.each do |inner|
        former = inner.name
        self.extend_name!(inner)
        self.replace_names_subs!(former,inner.name)
    end
    # Returns the extracted declares.
    return decls
end
extract_from_externals!(stmnt,sym2var) click to toggle source

Extract the variables corresponding to external signals from block-based statement stmnt, and put the extraction result is table sym2var that associate variable with corresponding signal name.

# File lib/HDLRuby/hruby_low_with_var.rb, line 82
def extract_from_externals!(stmnt,sym2var)
    if (stmnt.is_a?(Block)) then
        # Block case, gather its declared and signals variables.
        vars = {}
        sigs = {}
        stmnt.each_inner do |inner|
            if variable_name?(inner.name) then
                vars[inner.name] = inner
            else
                sigs[inner.name] = inner
            end
        end
        # Select the variables that correspond to external signals.
        vars.each do |name,inner|
            sym = var_name2sym(name)
            unless sigs.key?(sym) then
                # The variable correspond to an external signal,
                # extract it.
                sym2var[sym] = inner
                stmnt.delete_inner(inner)
            end
        end
    elsif
        # Other case, recurse on the sub blocks.
        stmnt.each_block do |block|
            extract_from_externals!(block,sym2var)
        end
    end
end
flatten(mode = nil) click to toggle source

Process top layer of Block. Determine whether there is a block under block and convert it.

# File lib/HDLRuby/hruby_verilog.rb, line 243
def flatten(mode = nil)
    if self.is_a?(TimeBlock) then
        new_block = TimeBlock.new(self.mode,"")
    else
        new_block  = Block.new(self.mode,"") # A new block to store the converted statement.
    end
    list = []                            # A list for confirming that variable declarations do not overlap.

    # Is block in the statement?
    if (self.each_statement.find {|stmnt| stmnt.is_a?(Block)}) then
        # Process for each type of statement in block.
        self.each_statement do |statement|
            # If statement is case, there is a block for each default and when, so translate each.
            if statement.is_a?(Case) then
                if statement.default.is_a?(Block)
                    default = statement.default.flatten
                    new_default = Block.new(default.mode,"")

                    default.each_inner do |inner|          
                        # I read inner, but when I am par, I delete all '.
                        unless (list.include?(inner.name.to_s)) then
                            if (self.mode == :seq) || (inner.name.to_s.include? "#") then
                                list << inner.name.to_s
                                new_block.add_inner(inner.clone)
                            end            
                        end
                    end

                    default.each_statement do |statement|
                        # If statement is Transmit, it is an expression and should be processed.
                        if statement.is_a?(Transmit) then
                            # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
                            unless (res_name(statement.left).name.to_s.include? "'") || default.mode == :par then
                                # Prepare a new signal with the # on the variable on the left side using the att_signal method.
                                new_signal = att_signal(statement.left, "#")
                                # Check list and add new variables to inner if they do not duplicate.
                                unless (list.include?(new_signal.name.to_s)) then
                                    list << new_signal.name.to_s
                                    new_block.add_inner(new_signal)
                                end

                                new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)

                                $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")

                                $fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
                                new_default.add_statement(new_statement.clone)
                            else
                                new_default.add_statement(statement.clone)
                            end 
                        else
                            new_default.add_statement(statement.clone)
                        end
                    end     
                end

                new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])

                statement.each_when do |whens|
                    when_smt = whens.statement.flatten
                    new_when_smt = Block.new(when_smt.mode,"")

                    when_smt.each_statement do |statement|
                        # If statement is Transmit, it is an expression and should be processed.
                        if statement.is_a?(Transmit) then
                            # # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
                            unless (res_name(statement.left).name.to_s.include? "'") || when_smt.mode == :par then
                                # # Prepare a new signal with the # on the variable on the left side using the att_signal method.
                                new_signal = att_signal(statement.left, "#")
                                # Check list and add new variables to inner if they do not duplicate.
                                unless (list.include?(new_signal.name.to_s)) then
                                    list << new_signal.name.to_s
                                    new_block.add_inner(new_signal)
                                end

                                new_smt = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)

                                $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")

                                $fm.fm_par["#{statement.left.to_verilog}"] = new_smt.left
                                new_when_smt.add_statement(new_smt.clone)
                            else
                                new_when_smt.add_statement(statement.clone)
                            end 
                        else
                            new_when_smt.add_statement(statement.clone)
                        end
                    end

                    new_when = When.new(whens.match.clone,new_when_smt.clone)
                    new_statement.add_when(new_when.clone)
                end

                new_block.add_statement(new_statement)

                $fm.rep_sharp.each_key do |key|
                    new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
                    new_block.add_statement(new_smt.clone)
                end
                $fm.rep_sharp.clear() # Deactivate rep that has become obsolete.

                # If the statement is if, there is a block for each of yes, no, noifs, so translate each.
            elsif statement.is_a?(If) then   
                yes = statement.yes.flatten       # Smooth yes of if statement.
                new_yes = Block.new(yes.mode,"")  # New yes storage block

                yes.each_inner do |inner|          
                    # I read inner, but when I am par, I delete all '.
                    unless (list.include?(inner.name.to_s)) then
                        if (self.mode == :seq) || (inner.name.to_s.include? "#") then
                            list << inner.name.to_s
                            new_block.add_inner(inner.clone)
                        end            
                    end
                end

                # Check the statements in "yes" in order.
                yes.each_statement do |statement|
                    # If statement is Transmit, it is an expression and should be processed.
                    if statement.is_a?(Transmit) then
                        # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
                        unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then
                            # Prepare a new signal with the # on the variable on the left side using the att_signal method.
                            new_signal = att_signal(statement.left, "#")
                            # Check list and add new variables to inner if they do not duplicate.
                            unless (list.include?(new_signal.name.to_s)) then
                                list << new_signal.name.to_s
                                new_block.add_inner(new_signal)
                            end

                            new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)

                            $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")

                            new_yes.add_statement(new_statement.clone)


                            $fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left

                        else
                            new_yes.add_statement(statement.clone)
                        end 
                    else
                        new_yes.add_statement(statement.clone)
                    end
                end

                # Confirm that "else" exists and convert it if it exists.
                # Because error occurs when trying to convert when "else" does not exist.
                if statement.no.is_a? (Block) then
                    no = statement.no.flatten
                    new_no = Block.new(no.mode,"")

                    no.each_inner do |inner|          
                        # I read inner, but when I am par, I delete all '.
                        unless (list.include?(inner.name.to_s)) then
                            if (self.mode == :seq) || (inner.name.to_s.include? "#") then
                                list << inner.name.to_s
                                new_block.add_inner(inner.clone)
                            end            
                        end
                    end

                    no.each_statement do |statement|
                        # If statement is Transmit, it is an expression and should be processed.
                        if statement.is_a?(Transmit) then
                            # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
                            unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then

                                new_signal = att_signal(statement.left, "#")

                                # Double declaration of existing variable can not be done, so it is excluded.
                                unless (list.include?(new_signal.name.to_s)) then
                                    list << new_signal.name.to_s
                                    new_block.add_inner(new_signal)
                                end

                                new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)

                                $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")

                                $fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
                                new_no.add_statement(new_statement.clone)
                            else
                                new_no.add_statement(statement.clone)
                            end 
                        else
                            new_no.add_statement(statement.clone)
                        end
                    end
                end

                # Rebuild the converted "if" as a new" statement (If)".
                new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)

                # Just like "no", check if "noifs (elsif)" exists and if there is, take one by one and convert.
                # After that, add the converted "noif" to "If".
                statement.each_noif do |condition, block|
                    noif = block.flatten
                    new_noif = Block.new(noif.mode,"")

                    noif.each_inner do |inner|          
                        # I read inner, but when I am par, I delete all '.
                        unless (list.include?(inner.name.to_s)) then
                            if (self.mode == :seq) || (inner.name.to_s.include? "#") then
                                list << inner.name.to_s
                                new_block.add_inner(inner.clone)
                            end            
                        end
                    end


                    noif.each_statement do |statement|
                        # If statement is Transmit, it is an expression and should be processed.
                        if statement.is_a?(Transmit) then
                            # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
                            unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then

                                new_signal = att_signal(statement.left, "#")

                                # Double declaration of existing variable can not be done, so it is excluded.
                                unless (list.include?(new_signal.name.to_s)) then
                                    list << new_signal.name.to_s
                                    new_block.add_inner(new_signal)
                                end

                                new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)

                                $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")

                                $fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
                                new_noif.add_statement(new_statement.clone)
                            else
                                new_noif.add_statement(statement.clone)
                            end 
                        else
                            new_noif.add_statement(statement.clone)
                        end
                    end

                    new_statement.add_noif(condition.clone,new_noif.clone)
                end

                new_block.add_statement(new_statement.clone)

                $fm.rep_sharp.each_key do |key|
                    new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
                    new_block.add_statement(new_smt.clone)
                end
                $fm.rep_sharp.clear() # Deactivate rep that has become obsolete.

                # Process when "statement" is "Transmit" (just expression).
                # Record the expression in fm_par used for par-> seq and add the expression to new_block which is the "new block".
            elsif statement.is_a?(Transmit) then
                if self.mode == :seq then
                    $fm.fm_par["#{statement.left.to_verilog}"] = statement.right
                end
                new_block.add_statement(statement.clone)

                # When statement is Block (lower layer exists).
                # Smooth the lower layer with do_flat.
                # Add the added variables (inner) and expressions (statement) to new_block, respectively.
            elsif statement.is_a?(Block) then
                smt = statement.do_flat(self.mode)

                smt.each_inner do |inner|         
                    # I read inner, but when I am par, I delete all '.
                    unless (list.include?(inner.name.to_s)) then
                        if (self.mode == :seq) || (inner.name.to_s.include? "#") then
                            list << inner.name.to_s
                            new_block.add_inner(inner.clone)        
                        end
                    end
                end
                smt.each_statement do |tmt|
                    # Retrieve the RefName of the variable on the left side and store it in this_name.
                    if ((tmt.is_a? (Transmit)) && (self.mode == :seq)) then
                        $fm.fm_par["#{tmt.left.to_verilog}"] = tmt.right
                    end
                    new_block.add_statement(tmt.clone)           
                end
            else
                # Other statements are simply added as is.
                new_block.add_statement(statement.clone)
            end
        end

        return new_block # Return the new_block that completed the smoothing.

        # Processing when there is no block beneath.
        # Unlike ordinary "if" and "case" blocks come down, we check individually block under block.
    else
        self.each_statement do |statement|
            # If the if statement, convert it, otherwise add it as is
            if statement.is_a?(If) then
                # Since yes always exists, it is no problem even if it is converted as it is.
                yes = statement.yes.flatten 
                new_yes = Block.new(yes.mode,"")

                yes.each_inner do |inner|          
                    # I read inner, but when I am par, I delete all '.
                    unless (list.include?(inner.name.to_s)) then
                        if (yes.mode == :seq) || (inner.name.to_s.include? "#") then
                            list << inner.name.to_s
                            new_block.add_inner(inner.clone)
                        end            
                    end
                end

                # Check the statements in "yes" in order.
                yes.each_statement do |statement|
                    # If statement is Transmit, it is an expression and should be processed.
                    if statement.is_a?(Transmit) then
                        # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
                        unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then
                            # Generate a new signal to return #.
                            new_signal = att_signal(statement.left, "#")

                            # Double declaration of existing variable can not be done, so it is excluded.
                            unless (list.include?(new_signal.name.to_s)) then
                                list << new_signal.name.to_s
                                new_block.add_inner(new_signal)
                            end

                            new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)

                            $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")

                            $fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
                            new_yes.add_statement(new_statement.clone)
                        else
                            new_yes.add_statement(statement.clone)
                        end 
                    else
                        new_yes.add_statement(statement.clone)
                    end
                end

                # Confirm that "else" exists and convert it if it exists.
                # Because error occurs when trying to convert when "else" does not exist.
                if statement.no.is_a? (Block) then          
                    no = statement.no.flatten
                    new_no = Block.new(no.mode,"")

                    no.each_inner do |inner|          
                        # I read inner, but when I am par, I delete all '.
                        unless (list.include?(inner.name.to_s)) then
                            if (no.mode == :seq) || (inner.name.to_s.include? "#") then
                                list << inner.name.to_s
                                new_block.add_inner(inner.clone)
                            end            
                        end
                    end

                    no.each_statement do |statement|
                        # If statement is Transmit, it is an expression and should be processed.
                        if statement.is_a?(Transmit) then
                            # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
                            unless (res_name(statement.left).name.to_s.include? "'") || no.mode == :par then

                                new_signal = att_signal(statement.left, "#")

                                # Double declaration of existing variable can not be done, so it is excluded.
                                unless (list.include?(new_signal.name.to_s)) then
                                    list << new_signal.name.to_s
                                    new_block.add_inner(new_signal)
                                end

                                new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)

                                $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")

                                $fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
                                new_no.add_statement(new_statement.clone)
                            else
                                new_no.add_statement(statement.clone)
                            end 
                        else
                            new_no.add_statement(statement.clone)
                        end
                    end
                end
                # Rebuild the converted "if" as a new" statement (If)".
                new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
                # Just like "no", check if "noifs (elsif)" exists and if there is, take one by one and convert.
                # After that, add the converted "noif" to "If".
                statement.each_noif do |condition, block|

                    noif = block.flatten
                    new_noif = Block.new(noif.mode,"")

                    noif.each_inner do |inner|          
                        # I read inner, but when I am par, I delete all '.
                        unless (list.include?(inner.name.to_s)) then
                            if (noif.mode == :seq) || (inner.name.to_s.include? "#") then
                                list << inner.name.to_s
                                new_block.add_inner(inner.clone)
                            end            
                        end
                    end


                    noif.each_statement do |statement|
                        # If statement is Transmit, it is an expression and should be processed.
                        if statement.is_a?(Transmit) then
                            # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
                            unless (res_name(statement.left).name.to_s.include? "'") || noif.mode == :par then

                                new_signal = att_signal(statement.left, "#")

                                # Double declaration of existing variable can not be done, so it is excluded.
                                unless (list.include?(new_signal.name.to_s)) then
                                    list << new_signal.name.to_s
                                    new_block.add_inner(new_signal)
                                end

                                new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)

                                $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")

                                $fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
                                new_noif.add_statement(new_statement.clone)
                            else
                                new_noif.add_statement(statement.clone)
                            end 
                        else
                            new_noif.add_statement(statement.clone)
                        end
                    end

                    new_statement.add_noif(condition.clone,new_noif.clone)
                end

                new_block.add_statement(new_statement.clone)

                $fm.rep_sharp.each_key do |key|
                    new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
                    new_block.add_statement(new_smt.clone)
                end
                $fm.rep_sharp.clear() # Deactivate rep that has become obsolete.

            elsif statement.is_a?(Case) then
                if statement.default.is_a?(Block)
                    new_default = statement.default.flatten
                end

                new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
                statement.each_when do |whens|
                    new_when_statement = whens.statement.flatten
                    new_when = When.new(whens.match.clone,new_when_statement.clone)

                    new_statement.add_when(new_when.clone)
                end

                new_block.add_statement(new_statement)
            else          
                new_block.add_statement(statement.clone)
            end
        end    
        return new_block
    end
end
get_by_name(name) click to toggle source

Find an inner object by name. NOTE: return nil if not found.

# File lib/HDLRuby/hruby_low_resolve.rb, line 78
def get_by_name(name)
    # Ensure the name is a symbol.
    name = name.to_sym
    # Look in the signals.
    return self.get_inner(name)
end
get_inner(name) click to toggle source

Gets an inner signal by name.

# File lib/HDLRuby/hruby_low.rb, line 4078
def get_inner(name)
    return @inners[name.to_sym]
end
Also aliased as: get_signal
get_signal(name)
Alias for: get_inner
get_variable(name) click to toggle source

Gets a variable by name.

# File lib/HDLRuby/hruby_low_with_var.rb, line 147
def get_variable(name)
    # Ensure name is a symbol.
    name = name.to_sym
    # Get the variable.
    return variables[name]
end
hash() click to toggle source

Hash function.

# File lib/HDLRuby/hruby_low.rb, line 4044
def hash
    return [@mode,@name,@inners,@statements].hash
end
insert_statement!(idx,stmnt) click to toggle source

Inserts statement *stmnt+ at index idx.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1123
def insert_statement!(idx,stmnt)
    # Checks the index.
    if idx > @statements.size then
        raise AryError, "Index out of range: #{idx}"
    end
    # Checks the statement.
    unless stmnt.is_a?(Statement)
        raise AnyError, "Invalid type for a statement: #{stmnt.class}"
    end
    # Inserts the statement.
    @statements.insert(idx,stmnt)
    stmnt.parent = self
end
last_statement() click to toggle source

Returns the last statement.

# File lib/HDLRuby/hruby_low.rb, line 4160
def last_statement
    return @statements[-1]
end
map_inners!(&ruby_block) click to toggle source

Maps on the inners.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1103
def map_inners!(&ruby_block)
    @inners.map! do |inner|
        inner = ruby_block.call(inner)
        inner.parent = self unless inner.parent
        inner
    end
end
map_nodes!(&ruby_block)
Alias for: map_statements!
map_statements!(&ruby_block) click to toggle source

Maps on the statements.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1167
def map_statements!(&ruby_block)
    @statements.map! do |stmnt|
        stmnt = ruby_block.call(stmnt)
        stmnt.parent = self unless stmnt.parent
        stmnt
    end
end
Also aliased as: map_nodes!
mix?(mode = nil) click to toggle source

Tell if there is a mix block. mode is the mode of the upper block.

# File lib/HDLRuby/hruby_low2seq.rb, line 238
def mix?(mode = nil)
    # Check if different from mode block if any.
    return true if mode && self.type != mode
    # No difference with the upper block, maybe there is one within.
    # Check each statement.
    self.each_statement.any? { |stmt| stmnt.mix?(mode) }
end
num_statements() click to toggle source

Gets the number of statements.

# File lib/HDLRuby/hruby_low.rb, line 4133
def num_statements
    return @statements.size
end
par_in_seq2seq!() click to toggle source

Converts par blocks within seq blocks to seq blocks.

# File lib/HDLRuby/hruby_low_without_parinseq.rb, line 106
def par_in_seq2seq!
    # Recurse on the sub blocks.
    self.each_statement(&:par_in_seq2seq!)
    # Is the current block a seq block?
    if self.mode == :seq then
        # Yes, convert its inner par blocks to seq blocks.
        self.each_statement do |statement|
            if (statement.is_a?(Block)) then
                statement.to_seq! if statement.mode == :par
            end
        end
    end
    return self
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 1208
def reassign_expressions!(node2reassign)
    # Build the replacement table.
    node2rep = node2reassign.map {|n,r| [n,r[0]] }.to_h

    # First recurse on the sub blocks.
    # self.each_block { |block| block.reassign_expressions!(node2rep) }
    self.each_block { |block| block.reassign_expressions!(node2reassign) }

    # Now work on the block.
    # Replace on the statements.
    self.map_statements! do |statement|
        # Do the replacement
        node2rep_done = statement.replace_expressions!(node2rep)
        # Assign the replaced nodes in a new block.
        unless node2rep_done.empty?
            blk = Block.new(:seq)
            node2rep_done.each do |node,rep|
                reassign = node2reassign[node][1].clone
                blk.add_statement(Transmit.new(reassign,node.clone))
            end
            blk.add_statement(statement.clone)
            blk
        else
            statement
        end
    end
end
refs_by_variables!(stmnt,sym2var) click to toggle source

Replaces the references by corresponding variables in stmnt from sym2var table.

# File lib/HDLRuby/hruby_low_with_var.rb, line 115
def refs_by_variables!(stmnt,sym2var)
    # First, recurse.
    if stmnt.respond_to?(:each_node) then
        stmnt.each_node {|elem| refs_by_variables!(elem,sym2var) }
    end
    # Now replace an element if required.
    if stmnt.respond_to?(:map_nodes!) then
        stmnt.map_nodes! do |elem| 
            var = sym2var[elem.to_sym]
            var ? var2ref(var) : elem
        end
    end
end
repeat_to_verilog!() click to toggle source

Extract and convert to verilog the TimeRepeat statements. NOTE: work only on the current level of the block (should be called through each_block_deep).

# File lib/HDLRuby/hruby_verilog.rb, line 188
def repeat_to_verilog!
    code = ""
    # Gather the TimeRepeat statements.
    repeats = self.each_statement.find_all { |st| st.is_a?(TimeRepeat) }
    # Remove them from the block.
    repeats.each { |st| self.delete_statement!(st) }
    # Generate them separately in timed always processes.
    repeats.each do |st|
        code << "   always #{st.delay.to_verilog} begin\n"

        # Perform "scheduling" using the method "flatten".
        block = st.statement.flatten(st.statement.mode.to_s)

        # Declaration of "inner" part within "always".
        block.each_inner do |inner|
            # if regs.include?(inner.name) then
            if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
                code << "      reg"
            else
                code << "      wire"
            end

            # Variable has "base", but if there is width etc, it is not in "base".
            # It is determined by an if.
            if inner.type.base? 
                if inner.type.base.base? 
                    code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog}"
                else
                    code << "#{inner.type.to_verilog} #{inner.to_verilog}"
                end
            else
                code << " #{inner.type.to_verilog}#{inner.to_verilog}"
            end
            if inner.value then
                # There is an initial value.
                code << " = #{inner.value.to_verilog}"
            end
            code << ";\n"
        end

        # Translate the block that finished scheduling.
        block.each_statement do |statement|
            code  << "\n      #{statement.to_verilog(block.mode.to_s)}"
        end

        $fm.fm_par.clear()

        code << "\n   end\n\n"
    end
    return code
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 1194
def replace_expressions!(node2rep)
    res = {}
    # Recurse on the children.
    self.each_node do |node|
        res.merge!(node.replace_expressions!(node2rep))
    end
    return res
end
replace_names!(former,nname) click to toggle source

Replaces recursively former name by nname until it is redeclared.

# File lib/HDLRuby/hruby_low_without_namespace.rb, line 713
def replace_names!(former,nname)
    # Stop here if the name is redeclared.
    return if self.each_inner.find {|inner| inner.name == former }
    # Recurse on the sub scopes and behaviors.
    replace_names_subs!(former,nname)
end
replace_names_subs!(former,nname) click to toggle source

Replaces recursively former name by nname until it is redeclared in the sub scopes and behaviors.

# File lib/HDLRuby/hruby_low_without_namespace.rb, line 706
def replace_names_subs!(former,nname)
    self.each_statement do |stmnt|
        stmnt.replace_names!(former,nname)
    end
end
replace_statement!(org,stmnt) click to toggle source

Replaces statement org by statement stmnt.

NOTE: does nothing if org is not present.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1157
def replace_statement!(org,stmnt)
    # Checks the statement.
    unless stmnt.is_a?(Statement)
        raise AnyError, "Invalid type for a statement: #{stmnt.class}"
    end
    idx = @statements.index(org)
    @statements[idx] = stmnt if idx
end
res_name(me) click to toggle source

Recursively search, return Refname.

# File lib/HDLRuby/hruby_verilog.rb, line 1353
def res_name(me)
    if me.is_a? (RefName) then
        return me
    else
        if me.ref.is_a? (RefName) then
            return RefName.new(me.ref.type, me.ref.ref.clone, me.ref.name.to_s)
        elsif me.ref.is_a? (RefIndex) then
            return res_name(me.ref)
        elsif me.ref.is_a? (RefRange) then
            return res_name(me.ref)
        end
    end
end
reverse_each_statement(&ruby_block) click to toggle source

Reverse iterates over the statements.

Returns an enumerator if no ruby block is given.

# File lib/HDLRuby/hruby_low.rb, line 4152
def reverse_each_statement(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:reverse_each_statement) unless ruby_block
    # A ruby block? Apply it on each statement.
    @statements.reverse_each(&ruby_block)
end
search_refname(me,att = "'") click to toggle source

Recursively search, add “att” to RefName and return.

# File lib/HDLRuby/hruby_verilog.rb, line 1339
def search_refname(me,att = "'")
    if me.is_a? (RefName) then
        return RefName.new(me.type, me.ref.clone, me.name.to_s + att)
    elsif me.ref.is_a? (RefName) then
        return RefName.new(me.ref.type, me.ref.ref.clone, me.ref.name.to_s + att)
    elsif me.ref.is_a? (RefIndex) then
        return RefIndex.new(me.ref.type, search_refname(me.ref), me.ref.index.clone)
    elsif me.ref.is_a? (RefRange) then
        my_range = me.ref.range
        return RefRange.new(me.ref.type, search_refname(me.ref), my_range.first.clone..my_range.last.clone)
    end
end
select2case!() click to toggle source

Breaks the assignments to concats.

NOTE: work on the direct sub statement only, not deeply.

# File lib/HDLRuby/hruby_low_without_select.rb, line 134
def select2case!
    # Check each statement.
    self.map_statements! do |stmnt|
        # Skip blocks that are treated through recursion.
        next stmnt if stmnt.is_a?(Block)
        # Work on the statement.
        # Extract the Select expressions.
        selects = stmnt.extract_selects!
        if selects.any? then
            # Generate a sequential block containing the cases.
            blk = LowWithoutSelect.selects2block(selects)
            # Adds the statement to the block.
            blk.add_statement(stmnt.clone)
            stmnt = blk
        end
        stmnt 
    end
end
set_mode!(mode) click to toggle source

Sets the mode.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1091
def set_mode!(mode)
    # Check and set the type.
    @mode = mode.to_sym
end
set_name!(name) click to toggle source

Sets the name.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1097
def set_name!(name)
    # Check and set the name.
    @name = name.to_sym
end
set_statement!(idx,stmnt) click to toggle source

Sets statement stmnt at index idx.

# File lib/HDLRuby/hruby_low_mutable.rb, line 1138
def set_statement!(idx,stmnt)
    # Checks the index.
    if idx > @statements.size then
        raise AryError, "Index out of range: #{idx}"
    end
    # Checks the statement.
    unless stmnt.is_a?(Statement)
        raise AnyError, "Invalid type for a statement: #{stmnt.class}"
    end
    # Detach the previous statement if any.
    @statements[idx].parent = nil if @statements[idx]
    # Set the new statement.
    @statements[idx] = stmnt
    stmnt.parent = self
end
sym2var_name(sym) click to toggle source

Converts symbol sym representing an HDLRuby reference to a variable name.

# File lib/HDLRuby/hruby_low_with_var.rb, line 63
def sym2var_name(sym)
    return ("%" + sym.to_s).to_sym
end
to_c(level = 0) click to toggle source

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

# File lib/HDLRuby/hruby_low2c.rb, line 1474
def to_c(level = 0)
    res = " " * (level)
    res << "#{Low2C.code_name(self)}();\n"
    return res
end
to_c_code(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 1378
def to_c_code(level = 0)
    # The resulting string.
    res = ""
    # puts "generating self=#{self.object_id}"

    # Declare the global variable holding the block.
    res << "Block #{Low2C.obj_name(self)};\n\n"

    # Generate the c code of the sub blocks if any.
    self.each_statement do |stmnt|
        stmnt.add_blocks_code(res,level)
    end

    # Generate the execution function.
    res << " " * level*3
    res << "void #{Low2C.code_name(self)}() {\n"
    # res << "printf(\"Executing #{Low2C.code_name(self)}...\\n\");"
    # Generate the statements.
    self.each_statement do |stmnt|
        res << stmnt.to_c(level+1)
    end
    # Close the execution function.
    res << " " * level*3
    res << "}\n\n"


    # Generate the signals.
    self.each_signal { |signal| res << signal.to_c(level) }

    # The header of the block.
    res << " " * level*3
    res << "Block #{Low2C.make_name(self)}() {\n"
    res << " " * (level+1)*3
    res << "Block block = malloc(sizeof(BlockS));\n"
    res << " " * (level+1)*3
    res << "block->kind = BLOCK;\n";

    # Sets the global variable of the block.
    res << "\n"
    res << " " * (level+1)*3
    res << "#{Low2C.obj_name(self)} = block;\n"

    # Set the owner if any.
    if self.parent then
        # Look for a block or behavior parent.
        true_parent = self.parent
        until true_parent.is_a?(Block) || true_parent.is_a?(Behavior)
               true_parent = true_parent.parent
        end
        # Set it as the real parent.
        res << " " * (level+1)*3
        res << "block->owner = (Object)" + 
               "#{Low2C.obj_name(true_parent)};\n"
    else
        res << "block->owner = NULL;\n"
    end

    # The name
    res << " " * (level+1)*3
    res << "block->name = \"#{self.name}\";\n"

    # Add the inner signals declaration.
    res << " " * (level+1)*3
    res << "block->num_inners = #{self.each_inner.to_a.size};\n"
    res << " " * (level+1)*3
    res << "block->inners = calloc(sizeof(SignalI)," +
           "block->num_inners);\n"
    self.each_inner.with_index do |inner,i|
        res << " " * (level+1)*3
        res << "block->inners[#{i}] = " +
               "#{Low2C.make_name(inner)}();\n"
    end

    # Sets the execution function.
    res << " " * (level+1)*3
    res << "block->function = &#{Low2C.code_name(self)};\n"

    # Generate creation of the sub blocks.
    self.each_statement do |stmnt|
        stmnt.add_make_block(res,level+1)
    end

    # Generate the Returns of the result.
    res << "\n"
    res << " " * (level+1)*3
    res << "return block;\n"

    # Close the block.
    res << " " * level*3
    res << "};\n\n"
    return res
end
to_ch() click to toggle source

Generates the content of the h file.

# File lib/HDLRuby/hruby_low2c.rb, line 1481
def to_ch
    # puts "to_ch for block=#{Low2C.obj_name(self)} with=#{self.each_inner.count} inners"
    res = ""
    # Declare the global variable holding the block.
    res << "extern Block #{Low2C.obj_name(self)};\n\n"

    # Generate the access to the function making the block. */
    res << "extern Block #{Low2C.make_name(self)}();\n\n"

    # Generate the accesses to the ports.
    self.each_inner  { |inner|  res << inner.to_ch }

    # Recurse on the statements.
    self.each_statement { |stmnt| res << stmnt.to_ch }


    return res
end
to_conversion(mode = nil, rst = true, rep = true) click to toggle source
# File lib/HDLRuby/hruby_verilog.rb, line 877
def to_conversion(mode = nil, rst = true, rep = true)
    flat = Block.new(mode,"")      # Block that stores results.
    new_yes = Block.new(mode,"")   # Block containing the new yes.
    new_no  = Block.new(mode,"")   # Block containing the new no.
    new_noif  = Block.new(mode,"") # Block containing the new noif.
    list = []

    if rst == false then
        fm_seq_backup = $fm.fm_seq.dup
    end

    # The statement is divided (since it is the lowest layer, there is only Transmit).
    self.each_statement do |statement|
        # Various processing is performed depending on the type of Transmit.
        # If the mode of the upper layer = its own mode, it compresses as it is.

        if(mode == self.mode) then        
            new_statement = statement.clone
            # In the case of an If statement, processing of if, else, elsif is performed.
        elsif statement.is_a?(Case) then

            if statement.default.is_a?(Block)
                rep_buckup = $fm.rep.dup
                $fm.rep.clear()
                default = statement.default.to_conversion(mode,false,false)
                $fm.rep.clear()
                rep_buckup.each_key do |key|
                    $fm.rep[key] = rep_buckup[key]
                end

                new_default = Block.new(default.mode,"")

                default.each_inner do |inner|          
                    # I read inner, but when I am par, I delete all '.
                    unless (list.include?(inner.name.to_s)) then
                        if (self.mode == :seq) || (inner.name.to_s.include? "#") then
                            list << inner.name.to_s
                            flat.add_inner(inner.clone)
                        end            
                    end
                end

                default.each_statement do |statement|
                    # If statement is Transmit, it is an expression and should be processed.
                    if statement.is_a?(Transmit) then
                        # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
                        unless (res_name(statement.left).name.to_s.include? "'") || default.mode == :par then
                            # Prepare a new signal with the # on the variable on the left side using the att_signal method.
                            new_signal = att_signal(statement.left, "#")
                            # Check list and add new variables to inner if they do not duplicate.
                            unless (list.include?(new_signal.name.to_s)) then
                                list << new_signal.name.to_s
                                flat.add_inner(new_signal)
                            end

                            new_smt = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)

                            $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")

                            $fm.fm_par["#{statement.left.to_verilog}"] = new_smt.left
                            new_default.add_statement(new_smt.clone)
                        else
                            new_default.add_statement(statement.clone)
                        end 
                    else
                        new_default.add_statement(statement.clone)
                    end
                end     
            end


            new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])

            statement.each_when do |whens|

                rep_buckup = $fm.rep.dup
                $fm.rep.clear()
                when_smt = whens.statement.to_conversion(mode,false,false)
                $fm.rep.clear()
                rep_buckup.each_key do |key|
                    $fm.rep[key] = rep_buckup[key]
                end

                new_when_smt = Block.new(when_smt.mode,"")

                when_smt.each_statement do |statement|
                    # If statement is Transmit, it is an expression and should be processed.
                    if statement.is_a?(Transmit) then
                        # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
                        unless (res_name(statement.left).name.to_s.include? "'") || when_smt.mode == :par then
                            # Prepare a new signal with the # on the variable on the left side using the att_signal method.
                            new_signal = att_signal(statement.left, "#")
                            # Check list and add new variables to inner if they do not duplicate.
                            unless (list.include?(new_signal.name.to_s)) then
                                list << new_signal.name.to_s
                                flat.add_inner(new_signal)
                            end

                            new_smt = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)

                            $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")

                            $fm.fm_par["#{statement.left.to_verilog}"] = new_smt.left
                            new_when_smt.add_statement(new_smt.clone)
                        else
                            new_when_smt.add_statement(statement.clone)
                        end 
                    else
                        new_when_smt.add_statement(statement.clone)
                    end
                end

                new_when = When.new(whens.match.clone,new_when_smt.clone)
                new_statement.add_when(new_when.clone)
            end

        elsif statement.is_a?(If) then

            rep_buckup = $fm.rep.dup
            $fm.rep.clear()
            yes = statement.yes.to_conversion(mode, false,false)
            $fm.rep.clear()
            rep_buckup.each_key do |key|
                $fm.rep[key] = rep_buckup[key]
            end

            yes.each_inner do |inner|
                unless (list.include?(inner.name.to_s)) then
                    if (yes.mode == :seq) || (inner.name.to_s.include? "#") then
                        list << inner.name.to_s
                        flat.add_inner(inner.clone) # It was new_block. why?
                    end            
                end
            end

            yes.each_statement do |smt|
                if(yes.mode == :seq) then
                    new_signal = att_signal(smt.left, "#")

                    unless (list.include?(new_signal.name.to_s)) then
                        list << new_signal.name.to_s
                        flat.add_inner(new_signal)
                    end

                    yes_statement = Transmit.new(search_refname(smt.left,"#"),smt.right.clone)

                    $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")

                    $fm.fm_par["#{smt.left.to_verilog}"] = yes_statement.left
                    new_yes.add_statement(yes_statement)
                else
                    new_yes.add_statement(smt.clone)
                end
            end

            if statement.no.is_a? (Block) then
                rep_buckup = $fm.rep.dup
                $fm.rep.clear()
                no = statement.no.to_conversion(mode,false,false)
                $fm.rep.clear()
                rep_buckup.each_key do |key|
                    $fm.rep[key] = rep_buckup[key]
                end

                no.each_inner do |inner|
                    unless (list.include?(inner.name.to_s)) then
                        if (no.mode == :seq) || (inner.name.to_s.include? "#") then
                            list << inner.name.to_s
                            flat.add_inner(inner.clone) # It was new_block. why?
                        end            
                    end
                end

                no.each_statement do |smt|
                    if(no.mode == :seq) then
                        new_signal = att_signal(smt.left, "#")

                        unless (list.include?(new_signal.name.to_s)) then
                            list << new_signal.name.to_s
                            flat.add_inner(new_signal)
                        end

                        no_statement = Transmit.new(search_refname(smt.left,"#"),smt.right.clone)

                        $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")

                        $fm.fm_par["#{smt.left.to_verilog}"] = no_statement.left
                        new_no.add_statement(no_statement)
                    else
                        new_no.add_statement(smt.clone)
                    end
                end
            end

            new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)

            statement.each_noif do |condition, block|
                rep_buckup = $fm.rep.dup
                $fm.rep.clear()
                noif = block.to_conversion(mode,false,false)
                $fm.rep.clear()
                rep_buckup.each_key do |key|
                    $fm.rep[key] = rep_buckup[key]
                end

                noif.each_inner do |inner|
                    unless (list.include?(inner.name.to_s)) then
                        if (noif.mode == :seq) || (inner.name.to_s.include? "#") then
                            list << inner.name.to_s
                            flat.add_inner(inner.clone) # It was new_block. why?
                        end            
                    end
                end

                noif.each_statement do |smt|
                    if(noif.mode == :seq) then
                        new_signal = att_signal(smt.left, "#")

                        unless (list.include?(new_signal.name.to_s)) then
                            list << new_signal.name.to_s
                            flat.add_inner(new_signal)
                        end

                        noif_statement = Transmit.new(search_refname(smt.left,"#"),smt.right.clone)

                        $fm.rep_sharp[statement.left] = search_refname(statement.left,"#")

                        $fm.fm_par["#{smt.left.to_verilog}"] = noif_statement.left
                        new_noif.add_statement(no_statement)
                    else
                        new_noif.add_statement(smt.clone)
                    end
                end

                new_statement.add_noif(condition.clone,new_noif.clone)
            end

            # Otherwise, it is necessary to process par-> seq or seq-> par.
        else       
            # Make sure the right side is a formula (Binary).
            if statement.right.is_a?(Binary) then
                # Check the right side and the left side, and if they are variables, check the corresponding expressions and replace them.
                # If it is not a variable, it calls the method to be searched.
                if statement.right.left.is_a? (Ref) then               
                    if (mode == :par && self.mode == :seq) && $fm.fm_seq.has_key?(statement.right.left.to_verilog) then
                        statement_left = $fm.fm_seq["#{statement.right.left.to_verilog}"]
                    elsif (mode == :seq && self.mode == :par) && $fm.fm_par.has_key?(statement.right.left.to_verilog) then
                        statement_left = $fm.fm_par["#{statement.right.left.to_verilog}"]
                    else
                        statement_left = statement.right.left.clone
                    end
                elsif statement.right.left.is_a? (Binary) then  
                    statement_left = statement.right.left.to_change(self.mode)
                else
                    statement_left = statement.right.left.clone
                end

                if statement.right.right.is_a? (Ref) then
                    if (mode == :par && self.mode == :seq) && $fm.fm_seq.has_key?(statement.right.right.to_verilog) then
                        statement_right = $fm.fm_seq["#{statement.right.right.to_verilog}"]
                    elsif (mode == :seq && self.mode == :par) && $fm.fm_par.has_key?(statement.right.right.to_verilog) then
                        statement_right = $fm.fm_par["#{statement.right.right.to_verilog}"]
                    else
                        statement_right = statement.right.right.clone
                    end
                elsif statement.right.right.is_a? (Binary) then
                    statement_right = statement.right.right.to_change(self.mode)
                else
                    statement_right = statement.right.right.clone
                end   
                new_right = Binary.new(statement.right.type,statement.right.operator,statement_left.clone,statement_right.clone)
                # Confirm whether it is a variable.
            elsif statement.right.is_a?(Ref) then
                if (mode == :par && self.mode == :seq) && $fm.fm_seq.has_key?(statement.right.to_verilog) then
                    new_right = $fm.fm_seq["#{statement.right.to_verilog}"].clone
                elsif (mode == :seq && self.mode == :par) && $fm.fm_par.has_key?(statement.right.to_verilog) then
                    new_right = $fm.fm_par["#{statement.right.to_verilog}"].clone
                else
                    new_right = statement.right.clone
                end
                # Because it is not a number. Put it in as it is.
            else
                new_right = statement.right.clone
            end

            if (mode == :par && self.mode == :seq) then
                # Dock the existing left hand side and the replaced right hand side to create a new expression.
                # Record the expression after conversion to hash to continue seq-> par.
                new_statement = Transmit.new(statement.left.clone,new_right)
                $fm.fm_seq["#{statement.left.to_verilog}"] = new_right
            elsif (mode == :seq && self.mode == :par) && (rep) then
                unless (res_name(statement.left).name.to_s.include? "#")
                    # Search the variable on the left side and give 'to the name.
                    new_signal = att_signal(statement.left,"'")

                    unless (list.include?(new_signal.name.to_s)) then
                        list << new_signal.name.to_s
                        flat.add_inner(new_signal)
                    end

                    new_statement = Transmit.new(search_refname(statement.left,"'"),new_right)

                    $fm.rep[statement.left] = new_statement     
                end
            else
                new_statement = Transmit.new(statement.left.clone,new_right)
            end          
        end
        # Add the converted statement to flat (because par -> par or seq -> seq will be added until then).

        if new_statement.is_a?(Transmit) then
            unless (mode == :par && self.mode == :seq) && (res_name(new_statement.left).name.to_s.include? "'") then
                flat.add_statement(new_statement.clone)
            end
        else
            flat.add_statement(new_statement.clone)
        end

        if (rep)
            $fm.rep_sharp.each_key do |key|
                new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
                flat.add_statement(new_smt.clone)
            end
            $fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
        end
    end
    # Add an expression after paragraph based on rep.
    # A complement expression like x = x '.
    $fm.rep.each_key do |key|
        new_statement = Transmit.new(key.clone,$fm.rep[key].left.clone)
        flat.add_statement(new_statement.clone)
    end
    $fm.rep.clear() # Deactivate rep that has become obsolete.


    # Since seq -> par is the end, fm_par is deleted.
    if (mode == :par && self.mode == :seq) then
        $fm.fm_seq.clear()
    end

    # In case of if statement (when rst == false) you can not convert no or else if you delete the contents of fm_seq.
    # Therefore, in this case restore the backup to restore.
    # This means that it is necessary to erase fm_seq once obtained in the if statement once.
    if(rst == false) then
        $fm.fm_seq.clear()
        fm_seq_backup.each_key do |key|
            $fm.fm_seq[key] = fm_seq_backup[key]
        end
    end

    return flat # Return flat finished checking.
end
to_hdr(level = 0, header = true, timed = false) click to toggle source

Generates the text of the equivalent hdr text. level is the hierachical level of the object. header tells if the header is to generate or not. timed tells if its a timed block.

# File lib/HDLRuby/hruby_low2hdr.rb, line 475
def to_hdr(level = 0, header = true, timed = false)
    # The resulting string.
    res = ""
    # Generate the header if required.
    if header then
        if timed then
            res << " " * (level*3) << "timed "
        else
            res << " " * (level*3) << "#{self.mode} "
        end
        unless self.name.empty? then
            res << ":" << Low2HDR.hdr_decl_name(self.name) << " "
        end
        res << "do\n"
    end
    level = level + 1 if header
    # Generate the inners declaration.
    self.each_inner do |inner|
        res << " " * (level*3)
        res << inner.type.to_hdr(level) 
        res << ".inner :" << Low2HDR.hdr_decl_name(inner.name) << "\n"
    end
    # Generate the statements.
    self.each_statement do |stmnt|
        res << stmnt.to_hdr(level)
    end
    # Close the block.
    if header then
        res << " " * ((level-1)*3) << "end\n"
    end
    # Return the result.
    return res
end
to_high() click to toggle source

Creates a new high block statement.

# File lib/HDLRuby/hruby_low2high.rb, line 338
def to_high
    # Create the new block statement.
    res = HDLRuby::High::Block.new(self.mode,self.name)
    # Add the statements.
    self.each_statement { |stmnt| res.add_statement(stmnt.to_high) }
    return res
end
to_seq!() click to toggle source

Convert the block to seq.

# File lib/HDLRuby/hruby_low_without_parinseq.rb, line 122
def to_seq!
    if self.mode == :par then
        # Need to convert.
        # First recurse on the sub blocks.
        self.each_statement(&:to_seq!)
        # Now replace each left value by a new signal for
        # differed assingment in seq.
        differeds = []
        self.each_statement do |statement|
            left = statement.left
            if statement.is_a?(Transmit) then
                sig = SignalI.new(HDLRuby.uniq_name,left.type)
                self.add_inner(sig)
                diff = RefName.new(left.type,RefThis.new,sig.name)
                differeds << [left,diff]
                statement.set_left!(diff)
            end
        end
        # Adds the differed assignments.
        differeds.each do |left,diff|
            self.add_statement(Transmit.new(left.clone,diff.clone))
        end
        # Change the mode.
        self.set_mode!(:seq)
    end
    return self
end
to_upper_space!() click to toggle source

Moves the declarations to the upper namespace.

# File lib/HDLRuby/hruby_low_without_namespace.rb, line 672
def to_upper_space!
    # Recurse on the statements.
    self.each_statement(&:to_upper_space!)

    # Extract the declares from the statements.
    decls = self.each_statement.map(&:extract_declares!)

    # Reinsert the extracted declares to self.
    decls.flatten.each { |decl| self.add_inner(decl) }
end
to_verilog(spc = 3) click to toggle source

Converts the system to Verilog code adding 'spc' spaces at the begining of each line.

# File lib/HDLRuby/hruby_verilog.rb, line 132
def to_verilog(spc = 3)
    code = "begin"
    if self.name && !self.name.empty? then
        vname = name_to_verilog(self.name)
        code << " : #{vname}"
        self.properties[:verilog_name] = vname
    end
    code << "\n" if block.each_inner.any?
    # Declaration of "inner" part within "always".
    block.each_inner do |inner|
        if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
            # code << "      reg"
            code << "#{" " * (spc+3)}reg"
        else
            code << "#{" " * (spc+3)}wire"
        end

        # Variable has "base", but if there is width etc, it is not in "base".
        # It is determined by an if.
        if inner.type.base? 
            if inner.type.base.base? 
                code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog}"
            else
                code << "#{inner.type.to_verilog} #{inner.to_verilog}"
            end
        else
            code << " #{inner.type.to_verilog}#{inner.to_verilog}"
        end
        if inner.value then
            # There is an initial value.
            code << " = #{inner.value.to_verilog}"
        end
        code << ";\n"
    end

    # Translate the block that finished scheduling.
    block.each_statement do |statement|
        # puts "#{statement.to_verilog(spc+3)}"
        if statement.is_a?(Block) then
            code << "\n#{" " * (spc+3)}#{statement.to_verilog(spc+3)}"
        else
            code  << "\n#{statement.to_verilog(spc+3)}"
        end
    end
    # Close the block."
    code << "\n#{" "*spc}end"
    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 variables and level is the hierachical level of the object.

NOTE: only the statements are generated, the remaining is assumed

to be handled by the upper scope.
# File lib/HDLRuby/hruby_low2vhd.rb, line 1093
def to_vhdl(vars, level = 0)
    # The resulting string.
    res = ""
    # Generate the statements.
    self.each_statement do |stmnt|
        res << stmnt.to_vhdl(vars,level)
    end
    # Return the result.
    return res
end
unshift_statement(statement) click to toggle source

Adds a statement and the begining of the block

NOTE: TimeWait is not supported unless for TimeBlock objects.

# File lib/HDLRuby/hruby_low.rb, line 4117
def unshift_statement(statement)
    unless statement.is_a?(Statement) then
        raise AnyError,
              "Invalid class for a statement: #{statement.class}"
    end
    if statement.is_a?(TimeWait) then
        raise AnyError,
              "Timed statements are not supported in common blocks."
    end
    @statements.unshift(statement)
    # And set its parent.
    statement.parent = self
    statement
end
var2ref(var) click to toggle source

Converts a variable to a reference to it.

# File lib/HDLRuby/hruby_low_with_var.rb, line 57
def var2ref(var)
    return RefName.new(var.type,RefThis.new,var.name)
end
var_name2sym(name) click to toggle source

Converts a variable name to the symbol giving the corresponding HDLRuby reference.

# File lib/HDLRuby/hruby_low_with_var.rb, line 69
def var_name2sym(name)
    return name[1..-1].to_sym
end
variable_name?(name) click to toggle source

Tell if a name is a variable one.

# File lib/HDLRuby/hruby_low_with_var.rb, line 74
def variable_name?(name)
    name[0] == "%"
end
variables() click to toggle source

Get access to the variables

# File lib/HDLRuby/hruby_low_with_var.rb, line 130
def variables
    # Initializes the set of variables if required.
    @variables ||= {}
    return @variables
end
with_var(upper = nil) click to toggle source

Converts to a variable-compatible block where upper is the upper block if any.

NOTE: the result is a new block.

# File lib/HDLRuby/hruby_low_with_var.rb, line 159
def with_var(upper = nil)
    # puts "with_var for #{self} with upper=#{upper}"
    # Recurse on the statements.
    new_stmnts = []
    self.each_statement do |stmnt|
        # Process stmnt
        if stmnt.respond_to?(:with_var) then
            # Can be converted
            stmnt = stmnt.with_var(self)
        else
            # Cannot be converted, simply clone.
            stmnt = stmnt.clone
        end
        # Adds the result.
        new_stmnts << stmnt
    end
    # Handle the cases that does not need directly a variable
    # convertion
    # Is the block a par?
    if self.mode == :par then
        # Yes, creates a new block with the new statements.
        block = Block.new(self.mode)
        self.each_inner { |inner| block.add_inner(inner.clone) }
        new_stmnts.each {|stmnt| block.add_statement(stmnt) }
        # Is the block within a seq?
        if upper && upper.mode == :seq then
            # Yes, converts to seq.
            # return self.to_seq
            return block.blocks2seq!
        end
        # No, simply return the block.
        # block = self.clone
        return block
    end

    # The block is a seq, convert it.
    # Treat the block
    sym2var = {} # The table of variable by corresponding signal name
    # Generate and replace the variables
    new_stmnts.each do |stmnt|
        unless stmnt.is_a?(Transmit) then
            # The statement is not a transmission, extract the
            # variables that correspond to external signals.
            extract_from_externals!(stmnt,sym2var)
        else 
            # Other case: transmission, the left value is to convert
            # to a variable, and the right values are to be updated
            # with the existing variables.
            # First convert the left value to the corresponding symbol.
            sym = stmnt.left.to_sym
            # puts "sym=#{sym}"
            var = sym2var[sym]
            unless var then
                var = SignalI.new(sym2var_name(sym),stmnt.left.type)
                sym2var[sym] = var
            end
            # Then replace the relevant references by corresponding
            # variables
            refs_by_variables!(stmnt,sym2var)
        end
    end
    # puts "sym2var=#{sym2var}"
    # Declare the variables in the top block.
    top = self.top_block
    # puts "top=#{top}"
    sym2var.each_value do |var|
        # puts "Adding var=#{var.name}"
        top.add_inner(var.clone) unless top.each_inner.find {|v| v.eql?(var) }
    end
    # Generate the new block.
    result = self.class.new(self.mode,self.name)
    # Adds the inner signals of current block.
    self.each_inner do |inner|
        result.add_inner(inner.clone)
    end
    # Adds the new statements.
    new_stmnts.each do |stmnt|
        result.add_statement(stmnt)
    end
    # Adds final statements assigning variables back to the orginal
    # signals.
    sym2var.each do |sym,var|
        result.add_statement(
            Transmit.new(sym.to_hdr.clone,var2ref(var)))
    end
    # End of the conversion.
    return result
end