class HDLRuby::High::Scope

Describes a scope for a system type

Constants

High

High-level libraries for describing digital hardware.

Attributes

name[R]

The name of the scope if any.

namespace[R]

The namespace

return_value[R]

The return value when building the scope.

Public Class Methods

new(name = :"", systemT = nil, &ruby_block) click to toggle source

Creates a new scope with possible name. If the scope is a top scope of a system, this systemT is given by systemT.

The proc ruby_block is executed for building the scope. If no block is provided, the scope is the top of a system and is filled by the instantiation procedure of the system.

Calls superclass method HDLRuby::Low::Scope::new
# File lib/HDLRuby/hruby_high.rb, line 807
def initialize(name = :"", systemT = nil, &ruby_block)
    # Initialize the scope structure
    super(name)

    # Initialize the set of grouped system instances.
    @groupIs = {}

    # Creates the namespace.
    @namespace = Namespace.new(self)

    # Register the scope if it is not the top scope of a system
    # (in which case the system has already be registered with
    # the same name).
    unless name.empty? or systemT then
        # Named scope, set the hdl-like access to the scope.
        obj = self # For using the right self within the proc
        High.space_reg(name) { obj }
    end

    # Initialize the set of exported inner signals and instances
    @exports = {}
    # Initialize the set of included systems.
    @includes = {}

    # Builds the scope if a ruby block is provided
    # (which means the scope is not the top of a system).
    self.build(&ruby_block) if block_given?
end

Public Instance Methods

add_export(name) click to toggle source

Adds a name to export.

NOTE: if the name do not corresponds to any inner signal nor instance, raise an exception.

# File lib/HDLRuby/hruby_high.rb, line 878
def add_export(name)
    # Check the name.
    name = name.to_sym
    # Look for construct to make public.
    # Maybe it is an inner signals.
    inner = self.get_inner(name)
    if inner then
        # Yes set it as export.
        @exports[name] = inner
        return
    end
    # No, maybe it is an instance.
    instance = self.get_systemI(name)
    if instance then
        # Yes, set it as export.
        @exports[name] = instance
        return
    end
    # No, error.
    raise AnyError, "Invalid name for export: #{name}"
end
add_groupI(name, *instances) click to toggle source

Adds a group of system instances named name.

# File lib/HDLRuby/hruby_high.rb, line 843
def add_groupI(name, *instances)
    # Ensure name is a symbol and is not already used for another
    # group.
    name = name.to_sym
    if @groupIs.key?(name)
        raise AnyError,
              "Group of system instances named #{name} already exist."
    end
    # Add the group.
    @groupIs[name.to_sym] = instances
    # Sets the parent of the instances.
    instances.each { |instance| instance.parent = self }
end
add_inout(signal) click to toggle source

Adds inout signal in the current system.

# File lib/HDLRuby/hruby_high.rb, line 991
def add_inout(signal)
    self.parent.add_inout(signal)
end
add_input(signal) click to toggle source

Adds input signal in the current system.

# File lib/HDLRuby/hruby_high.rb, line 981
def add_input(signal)
    self.parent.add_input(signal)
end
add_output(signal) click to toggle source

Adds output signal in the current system.

# File lib/HDLRuby/hruby_high.rb, line 986
def add_output(signal)
    self.parent.add_output(signal)
end
as(system) click to toggle source

Casts as an included system.

# File lib/HDLRuby/hruby_high.rb, line 1244
def as(system)
    # puts "as with name: #{system.name}"
    system = system.name if system.respond_to?(:name)
    # puts "includes are: #{@includes.keys}"
    return @includes[system].namespace
end
build(&ruby_block) click to toggle source

Build the scope by executing ruby_block.

NOTE: used when the scope is not the top of a system.

# File lib/HDLRuby/hruby_high.rb, line 939
def build(&ruby_block)
    # Set the namespace for buidling the scope.
    High.space_push(@namespace)
    # Build the scope.
    # @return_value = High.top_user.instance_eval(&ruby_block)
    res = High.top_user.instance_eval(&ruby_block)
    High.space_pop
    # Now gain access to the result within the sub scope.
    if (res.is_a?(HRef)) then
        @return_value = res.type.inner(HDLRuby.uniq_name)
        High.space_push(@namespace)
        @return_value <= res
        High.space_pop
    else
        @return_value = res
    end
    # This will be the return value.
    @return_value
end
build_top(base,*args) click to toggle source

Builds the scope using base as model scope with possible arguments args.

NOTE: Used by the instantiation procedure of a system.

# File lib/HDLRuby/hruby_high.rb, line 964
def build_top(base,*args)
    # Fills its namespace with the content of the base scope
    # (this latter may already contains access points if it has been
    #  opended for extension previously).
    @namespace.concat_namespace(base.namespace)
    High.space_push(@namespace)
    # Execute the instantiation block
    base.parent.each_instance_proc do |instance_proc|
        @return_value = High.top_user.instance_exec(*args,&instance_proc)
    end
    High.space_pop
end
code(*content, &ruby_block) click to toggle source

Declares a non-HDLRuby set of code chunks described by content and completed from ruby_block execution result. NOTE: content includes the events to activate the code on and

a description of the code as a hash assotiating names
to code text.
# File lib/HDLRuby/hruby_high.rb, line 1052
def code(*content, &ruby_block)
    # Process the content.
    # Separate events from code chunks descriptions.
    events, chunks = content.partition {|elem| elem.is_a?(Event) }
    # Generates a large hash from the code.
    chunks = chunks.reduce(:merge)
    # Adds the result of the ruby block if any.
    if ruby_block then
        chunks.merge(HDLRuby::High.top_user.instance_eval(&ruby_block))
    end
    # Create the chunk objects.
    chunks = chunks.each.map do |name,content|
        content = [*content]
        # Process the lumps
        content.map! do |lump|
            lump.respond_to?(:to_expr) ? lump.to_expr : lump
        end
        Chunk.new(name,*content)
    end
    # Create the code object.
    res = Code.new
    # Adds the events.
    events.each(&res.method(:add_event))
    # Adds the chunks.
    chunks.each(&res.method(:add_chunk))
    # Adds the resulting code to the current scope.
    HDLRuby::High.top_user.add_code(res)
    # Return the resulting code
    return res
end
cur_system() click to toggle source

Gets the current system.

# File lib/HDLRuby/hruby_high.rb, line 1253
def cur_system
    return HDLRuby::High.cur_system
end
each_export(&ruby_block) click to toggle source

Iterates over the exported constructs.

Returns an enumerator if no ruby block is given.

# File lib/HDLRuby/hruby_high.rb, line 903
def each_export(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_export) unless ruby_block
    # A block? Apply it on each input signal instance.
    @exports.each_value(&ruby_block)
    # And apply on the sub scopes if any.
    @scopes.each {|scope| scope.each_export(&ruby_block) }
end
each_groupI(&ruby_block) click to toggle source

Iterates over the group of system instances.

Returns an enumerator if no ruby block is given.

# File lib/HDLRuby/hruby_high.rb, line 867
def each_groupI(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_groupI) unless ruby_block
    # A block? Apply it on each input signal instance.
    @groupIs.each(&ruby_block)
end
each_included(&ruby_block) click to toggle source

Iterates over the included systems.

# File lib/HDLRuby/hruby_high.rb, line 913
def each_included(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_included) unless ruby_block
    # A block? Apply it on each included system.
    @includes.each_value(&ruby_block)
    # And apply on the sub scopes if any.
    @scopes.each {|scope| scope.each_included(&ruby_block) }
end
export(*names) click to toggle source

Sets the constructs corresponding to names as exports.

# File lib/HDLRuby/hruby_high.rb, line 1199
def export(*names)
    names.each {|name| self.add_export(name) }
end
fill_low(scopeL) click to toggle source

Fills a low level scope with self's contents.

NOTE: name conflicts are treated in the current NameStack state.

# File lib/HDLRuby/hruby_high.rb, line 1262
def fill_low(scopeL)
    # Adds the content of its included systems.
    @includes.each_value {|system| system.scope.fill_low(scopeL) }
    # Adds the declared local system types.
    # NOTE: in the current version of HDLRuby::High, there should not
    # be any of them (only eigen systems are real system types).
    self.each_systemT { |systemT| scopeL.add_systemT(systemT.to_low) }
    # Adds the local types.
    self.each_type { |type| scopeL.add_type(type.to_low) }
    # Adds the inner scopes.
    self.each_scope { |scope| scopeL.add_scope(scope.to_low) }
    # Adds the inner signals.
    self.each_inner { |inner| scopeL.add_inner(inner.to_low) }
    # Adds the instances.
    # Single ones.
    self.each_systemI do |systemI|
        # puts "Filling with systemI=#{systemI.name}"
        systemI_low = scopeL.add_systemI(systemI.to_low)
        # Also add the eigen system to the list of local systems.
        scopeL.add_systemT(systemI_low.systemT)
    end
    # Grouped ones.
    self.each_groupI do |name,systemIs|
        systemIs.each.with_index { |systemI,i|
            # Sets the name of the system instance
            # (required for conversion of further accesses).
            # puts "systemI.respond_to?=#{systemI.respond_to?(:name=)}"
            systemI.name = name.to_s + "[#{i}]"
            # And convert it to low
            systemI_low = scopeL.add_systemI(systemI.to_low())
            # Also add the eigen system to the list of local systems.
            scopeL.add_systemT(systemI_low.systemT)
        }
    end
    # Adds the code chunks.
    self.each_code { |code| scopeL.add_code(code.to_low) }
    # Adds the connections.
    self.each_connection { |connection|
        # puts "connection=#{connection}"
        scopeL.add_connection(connection.to_low)
    }
    # Adds the behaviors.
    self.each_behavior { |behavior|
        scopeL.add_behavior(behavior.to_low)
    }
end
get_groupI(name) click to toggle source

Access a group of system instances by name.

NOTE: the result is a copy of the group for avoiding side effects.

# File lib/HDLRuby/hruby_high.rb, line 860
def get_groupI(name)
    return @groupIs[name.to_sym].clone
end
hcase(value) click to toggle source

Creates a new case statement with a value used for deciding which block to execute.

NOTE:

* the when part is defined through the hwhen method.
* a new behavior is created to enclose the hcase.
# File lib/HDLRuby/hruby_high.rb, line 1176
def hcase(value)
    self.par do
        hcase(value)
    end
end
helse(mode = nil, &ruby_block) click to toggle source

Sets the block executed when the condition is not met to the block in mode generated by the execution of ruby_block.

Can only be used once.

NOTE: added to the hif of the last behavior.

# File lib/HDLRuby/hruby_high.rb, line 1145
def helse(mode = nil, &ruby_block)
    # There is a ruby_block: the helse is assumed to be with
    # the last statement of the last behavior.
    statement = self.last_behavior.last_statement
    # Completes the hif or the hcase statement.
    unless statement.is_a?(If) or statement.is_a?(Case) then
        raise AnyError, "Error: helse statement without hif nor hcase (#{statement.class})."
    end
    statement.helse(mode, &ruby_block)
end
helsif(condition, mode = nil, &ruby_block) click to toggle source

Sets the condition check when the condition is not met to the block, with a condition that when met lead to the execution of the block in mode generated by the ruby_block.

# File lib/HDLRuby/hruby_high.rb, line 1159
def helsif(condition, mode = nil, &ruby_block)
    # There is a ruby_block: the helse is assumed to be with
    # the last statement of the last behavior.
    statement = self.last_behavior.last_statement
    # Completes the hif statement.
    unless statement.is_a?(If) then
        raise AnyError, "Error: helsif statement without hif (#{statement.class})."
    end
    statement.helsif(condition, mode, &ruby_block)
end
hif(condition, mode = nil, &ruby_block) click to toggle source

Creates a new if statement with a condition that when met lead to the execution of the block in mode generated by the ruby_block.

NOTE:

* the else part is defined through the helse method.
* a behavior is created to enclose the hif.
# File lib/HDLRuby/hruby_high.rb, line 1133
def hif(condition, mode = nil, &ruby_block)
    self.par do
        hif(condition,mode,&ruby_block)
    end
end
hwhen(match, mode = nil, &ruby_block) click to toggle source

Sets the block of a case structure executed when the match is met to the block in mode generated by the execution of ruby_block.

Can only be used once.

# File lib/HDLRuby/hruby_high.rb, line 1186
def hwhen(match, mode = nil, &ruby_block)
    # There is a ruby_block: the helse is assumed to be with
    # the last statement of the last behavior.
    statement = @behaviors.last.last_statement
    # Completes the hcase statement.
    unless statement.is_a?(Case) then
        raise AnyError, "Error: hwhen statement without hcase (#{statement.class})."
    end
    statement.hwhen(match, mode, &ruby_block)
end
include(system,*args) click to toggle source

Include a system type with possible args instanciation arguments.

# File lib/HDLRuby/hruby_high.rb, line 1205
def include(system,*args)
    if @includes.key?(system.name) then
        raise AnyError, "Cannot include twice the same system."
    end
    # puts "Include system=#{system.name}"
    # Save the name of the included system, it will serve as key
    # for looking for the included expanded version.
    include_name = system.name
    # Expand the system to include
    system = system.expand(:"",*args)
    # Add the included system interface to the current one.
    if self.parent.is_a?(SystemT) then
        space = self.namespace
        # Interface signals
        # puts "i_name=#{i_name} @to_includes=#{@to_includes.size}"
        system.each_signal_with_included do |signal|
            # puts "signal=#{signal.name}"
            space.send(:define_singleton_method,signal.name) do
                signal
            end
        end
        # Exported objects
        system.each_export do |export|
            # puts "export=#{export.name}"
            space.send(:define_singleton_method,export.name) do
                export
            end
        end
        # Adds the task to execute on the instance.
        system.each_on_instance do |task|
            self.parent.on_instance(&task)
        end
    end
    # Adds it the list of includeds
    @includes[include_name] = system
    
end
inout(*names) click to toggle source

Declares high-level bit inout signals named names in the current system.

# File lib/HDLRuby/hruby_high.rb, line 1043
def inout(*names)
    self.parent.inout(*names)
end
input(*names) click to toggle source

Declares high-level bit input signals named names in the current system.

# File lib/HDLRuby/hruby_high.rb, line 1031
def input(*names)
    self.parent.input(*names)
end
make_inouts(type, *names) click to toggle source

Creates and adds a set of inouts typed type from a list of names in the current system.

NOTE: a name can also be a signal, is which case it is duplicated.

# File lib/HDLRuby/hruby_high.rb, line 1015
def make_inouts(type, *names)
    self.parent.make_inouts(type,*names)
end
make_inputs(type, *names) click to toggle source

Creates and adds a set of inputs typed type from a list of names in the current system.

NOTE: a name can also be a signal, is which case it is duplicated.

# File lib/HDLRuby/hruby_high.rb, line 999
def make_inputs(type, *names)
    self.parent.make_inputs(type,*names)
end
make_outputs(type, *names) click to toggle source

Creates and adds a set of outputs typed type from a list of names in the current system.

NOTE: a name can also be a signal, is which case it is duplicated.

# File lib/HDLRuby/hruby_high.rb, line 1007
def make_outputs(type, *names)
    self.parent.make_outputs(type,*names)
end
open(&ruby_block) click to toggle source

Opens for extension.

NOTE: actually executes ruby_block in the context.

# File lib/HDLRuby/hruby_high.rb, line 926
def open(&ruby_block)
    High.space_push(@namespace)
    res = High.top_user.instance_eval(&ruby_block)
    High.space_pop
    # Return the result of the execution so that it can be used
    # as an expression
    res
end
output(*names) click to toggle source

Declares high-level bit output signals named names in the current system.

# File lib/HDLRuby/hruby_high.rb, line 1037
def output(*names)
    self.parent.output(*names)
end
par(*events, &ruby_block) click to toggle source

Declares a high-level parallel behavior activated on a list of events, and built by executing ruby_block.

# File lib/HDLRuby/hruby_high.rb, line 1109
def par(*events, &ruby_block)
    # Preprocess the events.
    events.map! do |event|
        event.respond_to?(:to_event) ? event.to_event : event
    end
    # Create and add the resulting behavior.
    self.add_behavior(Behavior.new(:par,*events,&ruby_block))
end
seq(*events, &ruby_block) click to toggle source

Declares a high-level sequential behavior activated on a list of events, and built by executing ruby_block.

# File lib/HDLRuby/hruby_high.rb, line 1098
def seq(*events, &ruby_block)
    # Preprocess the events.
    events.map! do |event|
        event.respond_to?(:to_event) ? event.to_event : event
    end
    # Create and add the resulting behavior.
    self.add_behavior(Behavior.new(:seq,*events,&ruby_block))
end
sub(name = :"", &ruby_block) click to toggle source

Declares a sub scope with possible name and built from ruby_block.

# File lib/HDLRuby/hruby_high.rb, line 1084
def sub(name = :"", &ruby_block)
    # Creates the new scope.
    scope = Scope.new(name,&ruby_block)
    # puts "new scope=#{scope}"
    # Add it
    self.add_scope(scope)
    # puts "self=#{self}"
    # puts "self scopes=#{self.each_scope.to_a.join(",")}"
    # Use its return value
    return scope.return_value
end
timed(&ruby_block) click to toggle source

Declares a high-level timed behavior built by executing ruby_block. By default, timed behavior are sequential.

# File lib/HDLRuby/hruby_high.rb, line 1120
def timed(&ruby_block)
    # Create and add the resulting behavior.
    self.add_behavior(TimeBehavior.new(:seq,&ruby_block))
end
to_low() click to toggle source

Converts the scope to HDLRuby::Low.

# File lib/HDLRuby/hruby_high.rb, line 1310
def to_low()
    # Create the resulting low scope.
    # scopeL = HDLRuby::Low::Scope.new()
    scopeL = HDLRuby::Low::Scope.new(self.name)
    # For debugging: set the source high object
    scopeL.properties[:low2high] = self.hdr_id
    self.properties[:high2low] = scopeL

    # Push the private namespace for the low generation.
    High.space_push(@namespace)
    # Pushes on the name stack for converting the internals of
    # the system.
    High.names_push
    # Adds the content of the actual system.
    self.fill_low(scopeL)
    # Restores the name stack.
    High.names_pop
    # Restores the namespace stack.
    High.space_pop
    # Return theresulting system.
    return scopeL
end
to_ref() click to toggle source

Converts to a new reference.

# File lib/HDLRuby/hruby_high.rb, line 1020
def to_ref
    return RefObject.new(this,self)
end
to_user() click to toggle source

Converts to a namespace user.

# File lib/HDLRuby/hruby_high.rb, line 837
def to_user
    # Already a user.
    return self
end