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, Print, RefConcat, RefIndex, RefName, RefObject, RefRange, RefThis, Scope, Select, SignalC, SignalI, StringE, 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)
- 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)
- Char =
TypeSigned.new(:char,7..0)
- 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
-
.booting? ⇒ Boolean
Tells HDLRuby is currently booting.
-
.cur_behavior ⇒ Object
Gets the enclosing behavior if any.
-
.cur_block(level = 0) ⇒ Object
Gets the enclosing block if any.
-
.cur_scope(level = 0) ⇒ Object
Gets the enclosing scope if any.
-
.cur_system ⇒ Object
Gets the enclosing system type if any.
-
.define_type(name) ⇒ Object
Defines a basic type +name+.
-
.from_users(method) ⇒ Object
Gather the result of the execution of +method+ from all the users of the namespaces.
-
.in_behavior? ⇒ Boolean
Tell if we are in a behavior.
-
.in_system? ⇒ Boolean
Tells if within a system type.
-
.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+.
-
.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+.
-
.names_add(name) ⇒ Object
Adds a +name+ to the top of the stack.
-
.names_create(base) ⇒ Object
Creates and adds the new name from +base+ that do not collides with the exisiting names.
-
.names_has?(name) ⇒ Boolean
Checks if a +name+ is present in the stack.
-
.names_pop ⇒ Object
Pops from the name stack.
-
.names_push ⇒ Object
Pushes on the name stack.
-
.space_call(name, *args, &ruby_block) ⇒ Object
Looks up and calls method +name+ from the namespace stack with arguments +args+ and block +ruby_block+.
-
.space_each(&ruby_block) ⇒ Object
Iterates over each namespace.
-
.space_include?(namespace) ⇒ Boolean
Tells if +namespace+ in included within the stack.
-
.space_index(namespace) ⇒ Object
Gets the index of a +namespace+ within the stack.
-
.space_insert(index, namespace) ⇒ Object
Inserts +namespace+ at +index+.
-
.space_pop ⇒ Object
Pops a namespace.
-
.space_push(namespace) ⇒ Object
Pushes +namespace+.
-
.space_reg(name, &ruby_block) ⇒ Object
Registers hardware referencing method +name+ to the current namespace.
-
.space_top ⇒ Object
Gets the top of the namespaces stack.
-
.space_top=(top) ⇒ Object
sets the top namespace.
-
.top_block(level = 0) ⇒ Object
Gets the top enclosing block if any.
-
.top_user ⇒ Object
Gets construct whose namespace is the top of the namespaces stack.
Instance Method Summary collapse
-
#function(name, &ruby_block) ⇒ Object
Declares a function named +name+ using +ruby_block+ as body.
-
#infinity ⇒ Object
Gets the infinity.
-
#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.
-
#set_this(obj = proc { RefThis.new }) ⇒ Object
Sets the current this to +obj+.
-
#struct(content) ⇒ Object
Creates an unnamed structure type from a +content+.
-
#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.
-
#this ⇒ Object
Gives access to the this reference.
-
#typedef(name, &ruby_block) ⇒ Object
Declares a high-level generic type named +name+, and using +ruby_block+ for construction.
Class Method Details
.booting? ⇒ Boolean
Tells HDLRuby is currently booting.
17 18 19 |
# File 'lib/HDLRuby/hruby_high.rb', line 17 def self.booting? true end |
.cur_behavior ⇒ Object
Gets the enclosing behavior if any.
4099 4100 4101 |
# File 'lib/HDLRuby/hruby_high.rb', line 4099 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.
4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 |
# File 'lib/HDLRuby/hruby_high.rb', line 4127 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.
4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 |
# File 'lib/HDLRuby/hruby_high.rb', line 4112 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 ⇒ Object
Gets the enclosing system type if any.
4085 4086 4087 4088 4089 4090 4091 4092 4093 |
# File 'lib/HDLRuby/hruby_high.rb', line 4085 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+.
1574 1575 1576 1577 1578 1579 |
# 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) ⇒ Object
Gather the result of the execution of +method+ from all the users of the namespaces.
4060 4061 4062 4063 4064 4065 4066 4067 |
# File 'lib/HDLRuby/hruby_high.rb', line 4060 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.
4104 4105 4106 |
# File 'lib/HDLRuby/hruby_high.rb', line 4104 def self.in_behavior? top_user.is_a?(Block) end |
.in_system? ⇒ Boolean
Tells if within a system type.
4080 4081 4082 |
# File 'lib/HDLRuby/hruby_high.rb', line 4080 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.
3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 |
# File 'lib/HDLRuby/hruby_high.rb', line 3870 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.
3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 |
# File 'lib/HDLRuby/hruby_high.rb', line 3893 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.
4726 4727 4728 |
# File 'lib/HDLRuby/hruby_high.rb', line 4726 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.
4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 |
# File 'lib/HDLRuby/hruby_high.rb', line 4739 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.
4731 4732 4733 4734 4735 |
# File 'lib/HDLRuby/hruby_high.rb', line 4731 def self.names_has?(name) NameStack.find do |names| names.include?(name) end end |
.names_pop ⇒ Object
Pops from the name stack.
4721 4722 4723 |
# File 'lib/HDLRuby/hruby_high.rb', line 4721 def self.names_pop NameStack.pop end |
.names_push ⇒ Object
Pushes on the name stack.
4716 4717 4718 |
# File 'lib/HDLRuby/hruby_high.rb', line 4716 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+.
4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 |
# File 'lib/HDLRuby/hruby_high.rb', line 4160 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.
4072 4073 4074 4075 4076 4077 |
# File 'lib/HDLRuby/hruby_high.rb', line 4072 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.
4030 4031 4032 |
# File 'lib/HDLRuby/hruby_high.rb', line 4030 def self.space_include?(namespace) return Namespaces.include?(namespace) end |
.space_index(namespace) ⇒ Object
Gets the index of a +namespace+ within the stack.
4035 4036 4037 |
# File 'lib/HDLRuby/hruby_high.rb', line 4035 def self.space_index(namespace) return Namespaces.index(namespace) end |
.space_insert(index, namespace) ⇒ Object
Inserts +namespace+ at +index+.
4017 4018 4019 |
# File 'lib/HDLRuby/hruby_high.rb', line 4017 def self.space_insert(index,namespace) Namespaces.insert(index.to_i,namespace.to_namespace) end |
.space_pop ⇒ Object
Pops a namespace.
4022 4023 4024 4025 4026 4027 |
# File 'lib/HDLRuby/hruby_high.rb', line 4022 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+.
4009 4010 4011 4012 4013 4014 |
# File 'lib/HDLRuby/hruby_high.rb', line 4009 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.
4153 4154 4155 4156 |
# File 'lib/HDLRuby/hruby_high.rb', line 4153 def self.space_reg(name,&ruby_block) # print "registering #{name} in #{Namespaces[-1]}\n" Namespaces[-1].add_method(name,&ruby_block) end |
.space_top ⇒ Object
Gets the top of the namespaces stack.
4040 4041 4042 |
# File 'lib/HDLRuby/hruby_high.rb', line 4040 def self.space_top Namespaces[-1] end |
.space_top=(top) ⇒ Object
sets the top namespace.
4045 4046 4047 4048 4049 4050 |
# File 'lib/HDLRuby/hruby_high.rb', line 4045 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.
4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 |
# File 'lib/HDLRuby/hruby_high.rb', line 4139 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 ⇒ Object
Gets construct whose namespace is the top of the namespaces stack.
4054 4055 4056 |
# File 'lib/HDLRuby/hruby_high.rb', line 4054 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.
1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 |
# 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 # sub do # ruby_block.call(*args,*other_block) # 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 # sub do # ruby_block.call(*args,*other_block) # end end end end |
#infinity ⇒ Object
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.
1942 1943 1944 1945 1946 1947 |
# 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 }) ⇒ Object
Sets the current this to +obj+.
NOTE: do not use a this= style to avoid confusion.
3209 3210 3211 3212 3213 3214 3215 |
# File 'lib/HDLRuby/hruby_high.rb', line 3209 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+.
1888 1889 1890 |
# File 'lib/HDLRuby/hruby_high.rb', line 1888 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.
1931 1932 1933 1934 1935 |
# 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 ⇒ Object
Gives access to the this reference.
3219 3220 3221 3222 |
# File 'lib/HDLRuby/hruby_high.rb', line 3219 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.
1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 |
# 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 |