Module: HDLRuby::High

Defined in:
lib/HDLRuby/hruby_high.rb,
lib/HDLRuby/hruby_rsim.rb,
lib/HDLRuby/hruby_error.rb,
lib/HDLRuby/hruby_rcsim.rb,
lib/HDLRuby/hruby_rsim_vcd.rb,
lib/HDLRuby/hruby_rsim_mute.rb,
lib/HDLRuby/hruby_high_fullname.rb

Overview

Library for enhancing the Ruby simulator with muted output support

Defined Under Namespace

Modules: BlockHierarchy, HArrow, HBlock, HExpression, HRef, HScope_missing, HStatement, HbasicType, High2C, Hinner, Hmissing, Hmux, Htype, HvectorType, RCSimBehavior, RCSimBlock, SimSignal, SingletonExtend, Soft, Std, WithFullname Classes: AnyError, Behavior, Binary, Block, Case, Cast, Chunk, Code, Concat, Configure, Connection, Delay, Event, Expression, If, Namespace, NotDefinedError, Operation, Print, Program, Ref, RefConcat, RefIndex, RefName, RefObject, RefRange, RefThis, Scope, Select, SignalC, SignalI, Statement, StringE, SystemI, SystemT, TimeBehavior, TimeBlock, TimeRepeat, TimeTerminate, TimeWait, Transmit, Type, TypeDef, TypeFloat, TypeGen, TypeSigned, TypeStruct, TypeTuple, TypeUnsigned, TypeVector, UIError, 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)
StringT =

The string type

define_type(:string)
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,63..0)
Char =
TypeSigned.new(:char,7..0)
Natural =
TypeUnsigned.new(:natural,63..0)
Bignum =
TypeSigned.new(:bignum,HDLRuby::Infinity..0)
Real =
TypeFloat.new(:float)
RCSim =
RCSimCinterface
@@rsim_object_idstr =

Converts a HDLRuby object to a VCD id string.

{ }
@@rsim_object_idstr_count =
0

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.



4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
# File 'lib/HDLRuby/hruby_high.rb', line 4751

def self.cur_behavior
    # return @@cur_behavior
    if in_behavior? then
        user = top_user
        while(user && !user.is_a?(Behavior)) do
            user = user.parent
        end
        return user
    else
        return nil
    end
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.



4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
# File 'lib/HDLRuby/hruby_high.rb', line 4788

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

Gets the enclosing scope if any.

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



4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
# File 'lib/HDLRuby/hruby_high.rb', line 4773

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_systemObject

Gets the enclosing system type if any.



4737
4738
4739
4740
4741
4742
4743
4744
4745
# File 'lib/HDLRuby/hruby_high.rb', line 4737

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.



1836
1837
1838
1839
1840
1841
# File 'lib/HDLRuby/hruby_high.rb', line 1836

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.



4712
4713
4714
4715
4716
4717
4718
4719
# File 'lib/HDLRuby/hruby_high.rb', line 4712

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)


4765
4766
4767
# File 'lib/HDLRuby/hruby_high.rb', line 4765

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

.in_system?Boolean

Tells if within a system type.

Returns:

  • (Boolean)


4732
4733
4734
# File 'lib/HDLRuby/hruby_high.rb', line 4732

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.



4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
# File 'lib/HDLRuby/hruby_high.rb', line 4518

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.



4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
# File 'lib/HDLRuby/hruby_high.rb', line 4541

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.



5400
5401
5402
# File 'lib/HDLRuby/hruby_high.rb', line 5400

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.



5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
# File 'lib/HDLRuby/hruby_high.rb', line 5413

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)


5405
5406
5407
5408
5409
# File 'lib/HDLRuby/hruby_high.rb', line 5405

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

.names_popObject

Pops from the name stack.



5395
5396
5397
# File 'lib/HDLRuby/hruby_high.rb', line 5395

def self.names_pop
    NameStack.pop
end

.names_pushObject

Pushes on the name stack.



5390
5391
5392
# File 'lib/HDLRuby/hruby_high.rb', line 5390

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

.rcsim(top, name, outpath, outmode) ⇒ Object

Starts the simulation for top system top. NOTE: name is the name of the simulation, outpath is the path where the output is to save, and outmode is the output mode as follows: 0: standard 1: mute 2: vcd



87
88
89
# File 'lib/HDLRuby/hruby_rcsim.rb', line 87

def self.rcsim(top,name,outpath,outmode)
    RCSim.rcsim_main(top.rcsystemT,outpath +"/" + name,outmode)
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:



4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
# File 'lib/HDLRuby/hruby_high.rb', line 4821

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.



4724
4725
4726
4727
4728
4729
# File 'lib/HDLRuby/hruby_high.rb', line 4724

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)


4682
4683
4684
# File 'lib/HDLRuby/hruby_high.rb', line 4682

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

.space_index(namespace) ⇒ Object

Gets the index of a namespace within the stack.



4687
4688
4689
# File 'lib/HDLRuby/hruby_high.rb', line 4687

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

.space_insert(index, namespace) ⇒ Object

Inserts namespace at index.



4669
4670
4671
# File 'lib/HDLRuby/hruby_high.rb', line 4669

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

.space_popObject

Pops a namespace.



4674
4675
4676
4677
4678
4679
# File 'lib/HDLRuby/hruby_high.rb', line 4674

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.



4661
4662
4663
4664
4665
4666
# File 'lib/HDLRuby/hruby_high.rb', line 4661

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.



4814
4815
4816
4817
# File 'lib/HDLRuby/hruby_high.rb', line 4814

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.



4692
4693
4694
# File 'lib/HDLRuby/hruby_high.rb', line 4692

def self.space_top
    Namespaces[-1]
end

.space_top=(top) ⇒ Object

sets the top namespace.



4697
4698
4699
4700
4701
4702
# File 'lib/HDLRuby/hruby_high.rb', line 4697

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

Gets the top enclosing block if any.



4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
# File 'lib/HDLRuby/hruby_high.rb', line 4800

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_userObject

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



4706
4707
4708
# File 'lib/HDLRuby/hruby_high.rb', line 4706

def self.top_user
    self.space_top.user
end

.vcd_bitstr(str) ⇒ Object

Converts a bit string to a vcd format.



15
16
17
18
19
20
21
# File 'lib/HDLRuby/hruby_rsim_vcd.rb', line 15

def self.vcd_bitstr(str)
    if str.length > 1 then
        return "b" + str + " "
    else
        return str
    end
end

.vcd_idstr(obj) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/HDLRuby/hruby_rsim_vcd.rb', line 26

def self.vcd_idstr(obj)
    idstr = @@rsim_object_idstr[obj]
    unless idstr then
        # Must generate a new id string.
        chars = []
        id = @@rsim_object_idstr_count
        @@rsim_object_idstr_count += 1
        loop do
            chars << ((id % (127-33)) + 33).chr
            break if ((id=id/(127-33)) == 0)
        end
        idstr = chars.join
        @@rsim_object_idstr[obj] = idstr
    end
    return idstr
end

.vcd_name(name) ⇒ Object

Converts a HDLRuby name to a VCD name.



10
11
12
# File 'lib/HDLRuby/hruby_rsim_vcd.rb', line 10

def self.vcd_name(name)
    return name.to_s.gsub(/[^a-zA-Z0-9_$]/,"$")
end

Instance Method Details

#curry_with_context(*args, &ruby_block) ⇒ Object

Reimplementation of the Proc's curry that transmit the context for execution.



31
32
33
34
35
# File 'lib/HDLRuby/hruby_high.rb', line 31

def curry_with_context(*args,&ruby_block)
    return proc do |cxt,*new_args|
        cxt.instance_exec(*(args+new_args),&ruby_block)
    end
end

#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.



2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
# File 'lib/HDLRuby/hruby_high.rb', line 2225

def function(name, &ruby_block)
    warn("Construct 'function' is deprecated, use 'hdef' instead.")
    # Ensure there is a block.
    ruby_block = proc {} unless block_given?
    if HDLRuby::High.in_system? then
        define_singleton_method(name.to_sym) do |*args,&other_block|
            sub(HDLRuby.uniq_name(name)) do
                HDLRuby::High.top_user.instance_exec(*args,*other_block,
                                                     &ruby_block)
            end
        end
    else
        define_method(name.to_sym) do |*args,&other_block|
            sub(HDLRuby.uniq_name(name)) do
                HDLRuby::High.top_user.instance_exec(*args,*other_block,
                                                     &ruby_block)
            end
        end
    end
end

#hdef(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.



2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
# File 'lib/HDLRuby/hruby_high.rb', line 2249

def hdef(name, &ruby_block)
    # Ensure there is a block.
    ruby_block = proc {} unless block_given?
    if HDLRuby::High.in_system? then
        define_singleton_method(name.to_sym) do |*args,&other_block|
            res = nil
            sub(HDLRuby.uniq_name(name)) do
                res = HDLRuby::High.top_user.instance_exec(*args,
                                        *other_block, &ruby_block)
            end
            res
        end
    else
        define_method(name.to_sym) do |*args,&other_block|
            res = nil
            sub(HDLRuby.uniq_name(name)) do
                res = HDLRuby::High.top_user.instance_exec(*args,
                                        *other_block, &ruby_block)
            end
            res
        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.



2211
2212
2213
2214
2215
2216
2217
2218
# File 'lib/HDLRuby/hruby_high.rb', line 2211

def instance(name, *includes, &ruby_block)
    # Ensure there is a block.
    ruby_block = proc {} unless block_given?
    # Creates the system type.
    systemT = system(:"",*includes,&ruby_block)
    # Instantiate it with +name+.
    return systemT.instantiate(name) 
end

#set_this(obj = proc { RefThis.new }) ⇒ Object

Sets the current this to obj.

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



3751
3752
3753
3754
3755
3756
3757
# File 'lib/HDLRuby/hruby_high.rb', line 3751

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

Creates an unnamed structure type from a content.



2151
2152
2153
# File 'lib/HDLRuby/hruby_high.rb', line 2151

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.



2198
2199
2200
2201
2202
2203
2204
# File 'lib/HDLRuby/hruby_high.rb', line 2198

def system(name = :"", *includes, &ruby_block)
    # Ensure there is a block.
    ruby_block = proc {} unless block_given?
    # 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.



3761
3762
3763
3764
# File 'lib/HDLRuby/hruby_high.rb', line 3761

def this
    # RefThis.new
    @@this.call
end

#typedef(name, &ruby_block) ⇒ Object

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



2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
# File 'lib/HDLRuby/hruby_high.rb', line 2159

def typedef(name, &ruby_block)
    # Ensure there is a block.
    ruby_block = proc {} unless block_given?
    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)
                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