Module: HDLRuby::High

Defined in:
lib/HDLRuby/hruby_high.rb,
lib/HDLRuby/hruby_error.rb

Overview

High-level libraries for describing digital hardware.

Defined Under Namespace

Modules: HArrow, HBlock, HExpression, HRef, HScope_missing, HStatement, HbasicType, Hinner, Hmissing, Hmux, Htype, HvectorType, SingletonExtend, Std Classes: AnyError, Behavior, Binary, Block, Case, Cast, Chunk, Code, Concat, Connection, Delay, Event, If, Namespace, NotDefinedError, RefConcat, RefIndex, RefName, RefObject, RefRange, RefThis, Scope, Select, SignalC, SignalI, SystemI, SystemT, TimeBehavior, TimeBlock, TimeRepeat, TimeWait, Transmit, Type, TypeDef, TypeFloat, TypeGen, TypeSigned, TypeStruct, TypeTuple, TypeUnsigned, TypeVector, Unary, Value, When

Constant Summary collapse

Low =

Base = HDLRuby::Base

HDLRuby::Low
Void =

The void type

define_type(:void)
Bit =

The bit type.

define_type(:bit)
Signed =

The signed bit type.

define_type(:signed)
Unsigned =

The unsigned bit type.

define_type(:unsigned)
Float =

The float bit type

define_type(:float)
Universe =

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

SystemT.new(:"") {}
NameStack =

The stack of names for creating new names without conflicts.

[ Set.new ]
Integer =

Standard vector types.

TypeSigned.new(:integer)
Natural =
TypeUnsigned.new(:natural)
Bignum =
TypeSigned.new(:bignum,HDLRuby::Infinity..0)
Real =
TypeFloat.new(:float)
@@cur_behavior =

The current behavior: by default none.

nil

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.booting?Boolean

Tells HDLRuby is currently booting.

Returns:

  • (Boolean)


17
18
19
# File 'lib/HDLRuby/hruby_high.rb', line 17

def self.booting?
    true
end

.cur_behaviorObject

Gets the enclosing behavior if any.



3489
3490
3491
# File 'lib/HDLRuby/hruby_high.rb', line 3489

def self.cur_behavior
    return @@cur_behavior
end

.cur_block(level = 0) ⇒ Object

Gets the enclosing block if any.

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



3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
# File 'lib/HDLRuby/hruby_high.rb', line 3502

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_systemObject

Gets the enclosing system type if any.



3475
3476
3477
3478
3479
3480
3481
3482
3483
# File 'lib/HDLRuby/hruby_high.rb', line 3475

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) ⇒ Object

Defines a basic type name.



1465
1466
1467
1468
1469
1470
# File 'lib/HDLRuby/hruby_high.rb', line 1465

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) ⇒ Object

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



3450
3451
3452
3453
3454
3455
3456
3457
# File 'lib/HDLRuby/hruby_high.rb', line 3450

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?Boolean

Tell if we are in a behavior.

Returns:

  • (Boolean)


3494
3495
3496
# File 'lib/HDLRuby/hruby_high.rb', line 3494

def self.in_behavior?
    top_user.is_a?(Block)
end

.in_system?Boolean

Tells if within a system type.

Returns:

  • (Boolean)


3470
3471
3472
# File 'lib/HDLRuby/hruby_high.rb', line 3470

def self.in_system?
    return Namespaces.size > 1
end

.make_block(mode = nil, name = :"", &ruby_block) ⇒ Object

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.



3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
# File 'lib/HDLRuby/hruby_high.rb', line 3266

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) ⇒ Object

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.



3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
# File 'lib/HDLRuby/hruby_high.rb', line 3289

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) ⇒ Object

Adds a name to the top of the stack.



4020
4021
4022
# File 'lib/HDLRuby/hruby_high.rb', line 4020

def self.names_add(name)
    NameStack[-1].add(name.to_s)
end

.names_create(base) ⇒ Object

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



4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
# File 'lib/HDLRuby/hruby_high.rb', line 4033

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) ⇒ Boolean

Checks if a name is present in the stack.

Returns:

  • (Boolean)


4025
4026
4027
4028
4029
# File 'lib/HDLRuby/hruby_high.rb', line 4025

def self.names_has?(name)
    NameStack.find do |names|
        names.include?(name)
    end 
end

.names_popObject

Pops from the name stack.



4015
4016
4017
# File 'lib/HDLRuby/hruby_high.rb', line 4015

def self.names_pop
    NameStack.pop
end

.names_pushObject

Pushes on the name stack.



4010
4011
4012
# File 'lib/HDLRuby/hruby_high.rb', line 4010

def self.names_push
    NameStack.push(Set.new)
end

.space_call(name, *args, &ruby_block) ⇒ Object

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

Raises:



3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
# File 'lib/HDLRuby/hruby_high.rb', line 3521

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) ⇒ Object

Iterates over each namespace.

Returns an enumerator if no ruby block is given.



3462
3463
3464
3465
3466
3467
# File 'lib/HDLRuby/hruby_high.rb', line 3462

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) ⇒ Boolean

Tells if namespace in included within the stack.

Returns:

  • (Boolean)


3420
3421
3422
# File 'lib/HDLRuby/hruby_high.rb', line 3420

def self.space_include?(namespace)
    return Namespaces.include?(namespace)
end

.space_index(namespace) ⇒ Object

Gets the index of a namespace within the stack.



3425
3426
3427
# File 'lib/HDLRuby/hruby_high.rb', line 3425

def self.space_index(namespace)
    return Namespaces.index(namespace)
end

.space_insert(index, namespace) ⇒ Object

Inserts namespace at index.



3407
3408
3409
# File 'lib/HDLRuby/hruby_high.rb', line 3407

def self.space_insert(index,namespace)
    Namespaces.insert(index.to_i,namespace.to_namespace)
end

.space_popObject

Pops a namespace.



3412
3413
3414
3415
3416
3417
# File 'lib/HDLRuby/hruby_high.rb', line 3412

def self.space_pop
    if Namespaces.size <= 1 then
        raise AnyError, "Internal error: cannot pop further namespaces."
    end
    Namespaces.pop
end

.space_push(namespace) ⇒ Object

Pushes namespace.



3399
3400
3401
3402
3403
3404
# File 'lib/HDLRuby/hruby_high.rb', line 3399

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) ⇒ Object

Registers hardware referencing method name to the current namespace.



3514
3515
3516
3517
# File 'lib/HDLRuby/hruby_high.rb', line 3514

def self.space_reg(name,&ruby_block)
    # print "registering #{name} in #{Namespaces[-1]}\n"
    Namespaces[-1].add_method(name,&ruby_block)
end

.space_topObject

Gets the top of the namespaces stack.



3430
3431
3432
# File 'lib/HDLRuby/hruby_high.rb', line 3430

def self.space_top
    Namespaces[-1]
end

.space_top=(top) ⇒ Object

sets the top namespace.



3435
3436
3437
3438
3439
3440
# File 'lib/HDLRuby/hruby_high.rb', line 3435

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_userObject

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



3444
3445
3446
# File 'lib/HDLRuby/hruby_high.rb', line 3444

def self.top_user
    self.space_top.user
end

Instance Method Details

#function(name, &ruby_block) ⇒ Object

Declares a function named name using ruby_block as body.

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



1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
# File 'lib/HDLRuby/hruby_high.rb', line 1778

def function(name, &ruby_block)
    if HDLRuby::High.in_system? then
        define_singleton_method(name.to_sym) do |*args|
            sub do
                HDLRuby::High.top_user.instance_exec(*args,&ruby_block)
                # ruby_block.call(*args)
            end
        end
    else
        define_method(name.to_sym) do |*args|
            sub do
                HDLRuby::High.top_user.instance_exec(*args,&ruby_block)
            end
        end
    end
end

#infinityObject

Gets the infinity.



25
26
27
# File 'lib/HDLRuby/hruby_high.rb', line 25

def infinity
    return HDLRuby::Infinity
end

#instance(name, *includes, &ruby_block) ⇒ Object

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.



1766
1767
1768
1769
1770
1771
# File 'lib/HDLRuby/hruby_high.rb', line 1766

def instance(name, *includes, &ruby_block)
    # Creates the system type.
    systemT = system(:"",*includes,&ruby_block)
    # Instantiate it with +name+.
    return systemT.instantiate(name) 
end

#struct(content) ⇒ Object

Creates an unnamed structure type from a content.



1712
1713
1714
# File 'lib/HDLRuby/hruby_high.rb', line 1712

def struct(content)
    return TypeStruct.new(:"",:little,content)
end

#system(name = :"", *includes, &ruby_block) ⇒ Object

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



1755
1756
1757
1758
1759
# File 'lib/HDLRuby/hruby_high.rb', line 1755

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

#thisObject

Gives access to the this reference.



2708
2709
2710
# File 'lib/HDLRuby/hruby_high.rb', line 2708

def this
    RefThis.new
end

#typedef(name, &ruby_block) ⇒ Object

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



1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
# File 'lib/HDLRuby/hruby_high.rb', line 1720

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