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
Tells HDLRuby
is currently booting.
# File lib/HDLRuby/hruby_high.rb, line 17 def self.booting? true end
Gets the enclosing behavior if any.
# File lib/HDLRuby/hruby_high.rb, line 4089 def self.cur_behavior return @@cur_behavior end
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
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
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
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
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
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
Tells if within a system type.
# File lib/HDLRuby/hruby_high.rb, line 4070 def self.in_system? return Namespaces.size > 1 end
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
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
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
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
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
Pops from the name stack.
# File lib/HDLRuby/hruby_high.rb, line 4711 def self.names_pop NameStack.pop end
Pushes on the name stack.
# File lib/HDLRuby/hruby_high.rb, line 4706 def self.names_push NameStack.push(Set.new) end
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
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
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
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
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
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
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
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
Gets the top of the namespaces stack.
# File lib/HDLRuby/hruby_high.rb, line 4030 def self.space_top Namespaces[-1] end
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
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
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
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
Gets the infinity.
# File lib/HDLRuby/hruby_high.rb, line 25 def infinity return HDLRuby::Infinity end
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
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
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
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
Gives access to the this reference.
# File lib/HDLRuby/hruby_high.rb, line 3209 def this # RefThis.new @@this.call end
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