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, Configure, Connection, Delay, Event, If, Namespace, NotDefinedError, Print, RefConcat, RefIndex, RefName, RefObject, RefRange, RefThis, Scope, Select, SignalC, SignalI, StringE, SystemI, SystemT, TimeBehavior, TimeBlock, TimeRepeat, TimeTerminate, 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.
4336 4337 4338 |
# File 'lib/HDLRuby/hruby_high.rb', line 4336 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.
4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 |
# File 'lib/HDLRuby/hruby_high.rb', line 4364 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.
4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 |
# File 'lib/HDLRuby/hruby_high.rb', line 4349 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.
4322 4323 4324 4325 4326 4327 4328 4329 4330 |
# File 'lib/HDLRuby/hruby_high.rb', line 4322 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+.
1683 1684 1685 1686 1687 1688 |
# File 'lib/HDLRuby/hruby_high.rb', line 1683 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.
4297 4298 4299 4300 4301 4302 4303 4304 |
# File 'lib/HDLRuby/hruby_high.rb', line 4297 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.
4341 4342 4343 |
# File 'lib/HDLRuby/hruby_high.rb', line 4341 def self.in_behavior? top_user.is_a?(Block) end |
.in_system? ⇒ Boolean
Tells if within a system type.
4317 4318 4319 |
# File 'lib/HDLRuby/hruby_high.rb', line 4317 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.
4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 |
# File 'lib/HDLRuby/hruby_high.rb', line 4107 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.
4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 |
# File 'lib/HDLRuby/hruby_high.rb', line 4130 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.
4963 4964 4965 |
# File 'lib/HDLRuby/hruby_high.rb', line 4963 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.
4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 |
# File 'lib/HDLRuby/hruby_high.rb', line 4976 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.
4968 4969 4970 4971 4972 |
# File 'lib/HDLRuby/hruby_high.rb', line 4968 def self.names_has?(name) NameStack.find do |names| names.include?(name) end end |
.names_pop ⇒ Object
Pops from the name stack.
4958 4959 4960 |
# File 'lib/HDLRuby/hruby_high.rb', line 4958 def self.names_pop NameStack.pop end |
.names_push ⇒ Object
Pushes on the name stack.
4953 4954 4955 |
# File 'lib/HDLRuby/hruby_high.rb', line 4953 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+.
4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 |
# File 'lib/HDLRuby/hruby_high.rb', line 4397 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.
4309 4310 4311 4312 4313 4314 |
# File 'lib/HDLRuby/hruby_high.rb', line 4309 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.
4267 4268 4269 |
# File 'lib/HDLRuby/hruby_high.rb', line 4267 def self.space_include?(namespace) return Namespaces.include?(namespace) end |
.space_index(namespace) ⇒ Object
Gets the index of a +namespace+ within the stack.
4272 4273 4274 |
# File 'lib/HDLRuby/hruby_high.rb', line 4272 def self.space_index(namespace) return Namespaces.index(namespace) end |
.space_insert(index, namespace) ⇒ Object
Inserts +namespace+ at +index+.
4254 4255 4256 |
# File 'lib/HDLRuby/hruby_high.rb', line 4254 def self.space_insert(index,namespace) Namespaces.insert(index.to_i,namespace.to_namespace) end |
.space_pop ⇒ Object
Pops a namespace.
4259 4260 4261 4262 4263 4264 |
# File 'lib/HDLRuby/hruby_high.rb', line 4259 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+.
4246 4247 4248 4249 4250 4251 |
# File 'lib/HDLRuby/hruby_high.rb', line 4246 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.
4390 4391 4392 4393 |
# File 'lib/HDLRuby/hruby_high.rb', line 4390 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.
4277 4278 4279 |
# File 'lib/HDLRuby/hruby_high.rb', line 4277 def self.space_top Namespaces[-1] end |
.space_top=(top) ⇒ Object
sets the top namespace.
4282 4283 4284 4285 4286 4287 |
# File 'lib/HDLRuby/hruby_high.rb', line 4282 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.
4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 |
# File 'lib/HDLRuby/hruby_high.rb', line 4376 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.
4291 4292 4293 |
# File 'lib/HDLRuby/hruby_high.rb', line 4291 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.
2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 |
# File 'lib/HDLRuby/hruby_high.rb', line 2063 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) # 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.
2051 2052 2053 2054 2055 2056 |
# File 'lib/HDLRuby/hruby_high.rb', line 2051 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.
3410 3411 3412 3413 3414 3415 3416 |
# File 'lib/HDLRuby/hruby_high.rb', line 3410 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+.
1997 1998 1999 |
# File 'lib/HDLRuby/hruby_high.rb', line 1997 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.
2040 2041 2042 2043 2044 |
# File 'lib/HDLRuby/hruby_high.rb', line 2040 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.
3420 3421 3422 3423 |
# File 'lib/HDLRuby/hruby_high.rb', line 3420 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.
2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 |
# File 'lib/HDLRuby/hruby_high.rb', line 2005 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 |