module HDLRuby::High

High-level libraries for describing digital hardware.

Constants

Bignum
Bit

The bit type.

Char
Float

The float bit type

Integer

Standard vector types.

Low

Adds methods for allocating addresses to signals in Code objects.


Adds methods for allocating addresses to signals in Code objects and integrate the result into C code.


Low-level libraries for describing digital hardware.


NameStack

The stack of names for creating new names without conflicts.

Namespaces

The namespace stack: never empty, the top is a nameless system without input nor output.

Natural
Real
Signed

The signed bit type.

StringT

The string type

Universe

The universe, i.e., the top system type.

Unsigned

The unsigned bit type.

Void

The void type

Private Class Methods

booting?() click to toggle source

Tells HDLRuby is currently booting.

# File lib/HDLRuby/hruby_high.rb, line 17
def self.booting?
    true
end
cur_behavior() click to toggle source

Gets the enclosing behavior if any.

# File lib/HDLRuby/hruby_high.rb, line 4089
def self.cur_behavior
    return @@cur_behavior
end
cur_block(level = 0) click to toggle source

Gets the enclosing block if any.

NOTE: level allows to get an upper block of the currently enclosing

block.
# File lib/HDLRuby/hruby_high.rb, line 4117
def self.cur_block(level = 0)
    if Namespaces[-1-level].user.is_a?(Scope) then
        raise AnyError, 
              "Not within a block: #{Namespaces[-1-level].user.class}"
    elsif Namespaces[-1-level].user.is_a?(Block) then
        return Namespaces[-1-level].user
    else
        return cur_block(level+1)
    end
end
cur_scope(level = 0) click to toggle source

Gets the enclosing scope if any.

NOTE: level allows to get an upper scope of the currently enclosing

scope.
# File lib/HDLRuby/hruby_high.rb, line 4102
def self.cur_scope(level = 0)
    if level < 0 then
        raise AnyError, "Not within a scope: #{Namespaces[-1].user.class}"
    end
    if Namespaces[-1-level].user.is_a?(Scope) then
        return Namespaces[-1-level].user
    else
        return cur_scope(level+1)
    end
end
cur_system() click to toggle source

Gets the enclosing system type if any.

# File lib/HDLRuby/hruby_high.rb, line 4075
def self.cur_system
    if Namespaces.size <= 1 then
        raise AnyError, "Not within a system type."
    else
        return Namespaces.reverse_each.find do |space|
            space.user.is_a?(Scope) and space.user.parent.is_a?(SystemT)
        end.user.parent
    end
end
define_type(name) click to toggle source

Defines a basic type name.

# File lib/HDLRuby/hruby_high.rb, line 1574
def self.define_type(name)
    name = name.to_sym
    type = Type.new(name)
    self.send(:define_method,name) { type }
    return type
end
from_users(method) click to toggle source

Gather the result of the execution of method from all the users of the namespaces.

# File lib/HDLRuby/hruby_high.rb, line 4050
def self.from_users(method)
    Namespaces.reverse_each.reduce([]) do |res,space|
        user = space.user
        if user.respond_to?(method) then
            res += [*user.send(method)]
        end
    end
end
in_behavior?() click to toggle source

Tell if we are in a behavior.

# File lib/HDLRuby/hruby_high.rb, line 4094
def self.in_behavior?
    top_user.is_a?(Block)
end
in_system?() click to toggle source

Tells if within a system type.

# File lib/HDLRuby/hruby_high.rb, line 4070
def self.in_system?
    return Namespaces.size > 1
end
make_block(mode = nil, name = :"", &ruby_block) click to toggle source

Creates a block executed in mode, with possible name, that can be timed or not depending on the enclosing object and build it by executing the enclosing ruby_block.

NOTE: not a method to include since it can only be used with a behavior or a block. Hence set as module method.

# File lib/HDLRuby/hruby_high.rb, line 3860
def self.make_block(mode = nil, name = :"", &ruby_block)
    unless mode then
        # No type of block given, get a default one.
        if top_user.is_a?(Block) then
            # There is an upper block, use its mode.
            mode = top_user.mode
        else
            # There is no upper block, use :par as default.
            mode = :par
        end
    end
    if top_user.is_a?(TimeBlock) then
        return TimeBlock.new(mode,name,&ruby_block)
    else
        return Block.new(mode,name,&ruby_block)
    end
end
make_time_block(mode = nil, name = :"", &ruby_block) click to toggle source

Creates a specifically timed block in mode, with possible name and build it by executing the enclosing ruby_block.

NOTE: not a method to include since it can only be used with a behavior or a block. Hence set as module method.

# File lib/HDLRuby/hruby_high.rb, line 3883
def self.make_time_block(mode = nil, name = :"", &ruby_block)
    unless mode then
        # No type of block given, get a default one.
        if top_user.is_a?(Block) then
            # There is an upper block, use its mode.
            mode = block.mode
        else
            # There is no upper block, use :par as default.
            mode = :par
        end
    end
    return TimeBlock.new(mode,name,&ruby_block)
end
names_add(name) click to toggle source

Adds a name to the top of the stack.

# File lib/HDLRuby/hruby_high.rb, line 4716
def self.names_add(name)
    NameStack[-1].add(name.to_s)
end
names_create(base) click to toggle source

Creates and adds the new name from base that do not collides with the exisiting names.

# File lib/HDLRuby/hruby_high.rb, line 4729
def self.names_create(base)
    base = base.to_s.clone
    # Create a non-conflicting name
    if self.names_has?(base) then
        count = 0
        while (self.names_has?(base + count.to_s)) do
            count += 1
        end
        base << count.to_s
    end
    # Add and return it
    self.names_add(base)
    # puts "created name: #{base}"
    return base.to_sym
end
names_has?(name) click to toggle source

Checks if a name is present in the stack.

# File lib/HDLRuby/hruby_high.rb, line 4721
def self.names_has?(name)
    NameStack.find do |names|
        names.include?(name)
    end 
end
names_pop() click to toggle source

Pops from the name stack.

# File lib/HDLRuby/hruby_high.rb, line 4711
def self.names_pop
    NameStack.pop
end
names_push() click to toggle source

Pushes on the name stack.

# File lib/HDLRuby/hruby_high.rb, line 4706
def self.names_push
    NameStack.push(Set.new)
end
space_call(name,*args,&ruby_block) click to toggle source

Looks up and calls method name from the namespace stack with arguments args and block ruby_block.

# File lib/HDLRuby/hruby_high.rb, line 4150
def self.space_call(name,*args,&ruby_block)
    # print "space_call with name=#{name}\n"
    # Ensures name is a symbol.
    name = name.to_sym
    # Look from the top of the namespace stack.
    Namespaces.reverse_each do |space|
        # puts "space=#{space.singleton_methods}"
        if space.respond_to?(name) then
            # print "Found is space user with class=#{space.user.class}\n"
            # The method is found, call it.
            return space.send(name,*args,&ruby_block)
        elsif space.user.respond_to?(name) then
            # The method is found in the user, call it.
            return space.user.send(name,*args,&ruby_block)
        end
    end
    # Look in the global methods.
    if HDLRuby::High.respond_to?(name) then
        # Found.
        return HDLRuby::High.send(name,*args,&ruby_block)
    end
    # Not found.
    raise NotDefinedError,
          "undefined HDLRuby construct, local variable or method `#{name}'."
end
space_each(&ruby_block) click to toggle source

Iterates over each namespace.

Returns an enumerator if no ruby block is given.

# File lib/HDLRuby/hruby_high.rb, line 4062
def self.space_each(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:space_each) unless ruby_block
    # A block? Apply it on each system instance.
    Namespaces.each(&ruby_block)
end
space_include?(namespace) click to toggle source

Tells if namespace in included within the stack.

# File lib/HDLRuby/hruby_high.rb, line 4020
def self.space_include?(namespace)
    return Namespaces.include?(namespace)
end
space_index(namespace) click to toggle source

Gets the index of a namespace within the stack.

# File lib/HDLRuby/hruby_high.rb, line 4025
def self.space_index(namespace)
    return Namespaces.index(namespace)
end
space_insert(index,namespace) click to toggle source

Inserts namespace at index.

# File lib/HDLRuby/hruby_high.rb, line 4007
def self.space_insert(index,namespace)
    Namespaces.insert(index.to_i,namespace.to_namespace)
end
space_pop() click to toggle source

Pops a namespace.

# File lib/HDLRuby/hruby_high.rb, line 4012
def self.space_pop
    if Namespaces.size <= 1 then
        raise AnyError, "Internal error: cannot pop further namespaces."
    end
    Namespaces.pop
end
space_push(namespace) click to toggle source

Pushes namespace.

# File lib/HDLRuby/hruby_high.rb, line 3999
def self.space_push(namespace)
    # Emsure namespace is really a namespace.
    namespace = namespace.to_namespace
    # Adds the namespace to the top.
    Namespaces.push(namespace)
end
space_reg(name,&ruby_block) click to toggle source

Registers hardware referencing method name to the current namespace.

# File lib/HDLRuby/hruby_high.rb, line 4143
def self.space_reg(name,&ruby_block)
    # print "registering #{name} in #{Namespaces[-1]}\n"
    Namespaces[-1].add_method(name,&ruby_block)
end
space_top() click to toggle source

Gets the top of the namespaces stack.

# File lib/HDLRuby/hruby_high.rb, line 4030
def self.space_top
    Namespaces[-1]
end
space_top=(top) click to toggle source

sets the top namespace.

# File lib/HDLRuby/hruby_high.rb, line 4035
def self.space_top=(top)
    unless top.is_a?(Namespace) then
        raise "Invalid class for a Namspace: #{top.class}"
    end
    Namespaces[-1] = top
end
top_block(level = 0) click to toggle source

Gets the top enclosing block if any.

# File lib/HDLRuby/hruby_high.rb, line 4129
def self.top_block(level = 0)
    blk = cur_block(level)
    unless blk.is_a?(Block)
        raise AnyError,
            "Not within a block: #{blk.user.class}"
    end
    if Namespaces[-1-level-1].user.is_a?(Scope) then
        return blk
    else
        return top_block(level+1)
    end
end
top_user() click to toggle source

Gets construct whose namespace is the top of the namespaces stack.

# File lib/HDLRuby/hruby_high.rb, line 4044
def self.top_user
    self.space_top.user
end

Private Instance Methods

function(name, &ruby_block) click to toggle source

Declares a function named name using ruby_block as body.

NOTE: a function is a short-cut for a method that creates a scope.

# File lib/HDLRuby/hruby_high.rb, line 1954
def function(name, &ruby_block)
    if HDLRuby::High.in_system? then
        define_singleton_method(name.to_sym) do |*args,&other_block|
            # sub do
            sub(HDLRuby.uniq_name(name)) do
                HDLRuby::High.top_user.instance_exec(*args,*other_block,
                                                     &ruby_block)
                # ruby_block.call(*args)
            end
        end
    else
        define_method(name.to_sym) do |*args,&other_block|
            # sub do
            sub(HDLRuby.uniq_name(name)) do
                HDLRuby::High.top_user.instance_exec(*args,*other_block,
                                                     &ruby_block)
            end
        end
    end
end
infinity() click to toggle source

Gets the infinity.

# File lib/HDLRuby/hruby_high.rb, line 25
def infinity
    return HDLRuby::Infinity
end
instance(name, *includes, &ruby_block) click to toggle source

Declares a high-level system instance named name, with includes mixins system types and using ruby_block for instantiating.

NOTE: this is for generating directly an instance without declaring

it system type.
# File lib/HDLRuby/hruby_high.rb, line 1942
def instance(name, *includes, &ruby_block)
    # Creates the system type.
    systemT = system(:"",*includes,&ruby_block)
    # Instantiate it with +name+.
    return systemT.instantiate(name) 
end
set_this(obj = proc { RefThis.new }) click to toggle source

Sets the current this to obj.

NOTE: do not use a this= style to avoid confusion.

# File lib/HDLRuby/hruby_high.rb, line 3199
def set_this(obj = proc { RefThis.new })
    if (obj.is_a?(Proc)) then
        @@this = obj
    else
        @@this = proc { RefObject.new(RefThis.new,obj) }
    end
end
struct(content) click to toggle source

Creates an unnamed structure type from a content.

# File lib/HDLRuby/hruby_high.rb, line 1888
def struct(content)
    return TypeStruct.new(:"",:little,content)
end
system(name = :"", *includes, &ruby_block) click to toggle source

Declares a high-level system type named name, with includes mixins system types and using ruby_block for instantiating.

# File lib/HDLRuby/hruby_high.rb, line 1931
def system(name = :"", *includes, &ruby_block)
    # print "system ruby_block=#{ruby_block}\n"
    # Creates the resulting system.
    return SystemT.new(name,*includes,&ruby_block)
end
this() click to toggle source

Gives access to the this reference.

# File lib/HDLRuby/hruby_high.rb, line 3209
def this
    # RefThis.new
    @@this.call
end
typedef(name, &ruby_block) click to toggle source

Declares a high-level generic type named name, and using ruby_block for construction.

# File lib/HDLRuby/hruby_high.rb, line 1896
def typedef(name, &ruby_block)
    type = TypeGen.new(name,&ruby_block)
    if HDLRuby::High.in_system? then
        # Must be inside a scope.
        unless HDLRuby::High.top_user.is_a?(Scope) then
            raise AnyError, "A local type cannot be declared within a #{HDLRuby::High.top_user.class}."
        end
        define_singleton_method(name.to_sym) do |*args|
            if (args.size < ruby_block.arity) then
                # Not enough arguments get generic type as is.
                type
            else
                # There are arguments, specialize the type.
                gtype = type.generate(*args)
                # And add it as a local type of the system.
                HDLRuby::High.top_user.add_type(gtype)
            end
        end
    else
        define_method(name.to_sym) do |*args|
            if (args.size < ruby_block.arity) then
                # Not enough arguments, get generic type as is.
                type
            else
                # There are arguments, specialize the type.
                type.generate(*args)
            end
        end
    end
end