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, 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, 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
-
.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.
-
.rcsim(top, name, outpath, outmode) ⇒ Object
Starts the simulation for top system +top+.
-
.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.
-
.vcd_bitstr(str) ⇒ Object
Converts a bit string to a vcd format.
- .vcd_idstr(obj) ⇒ Object
-
.vcd_name(name) ⇒ Object
Converts a HDLRuby name to a VCD name.
Instance Method Summary collapse
-
#curry_with_context(*args, &ruby_block) ⇒ Object
Reimplementation of the Proc's curry that transmit the context for execution.
-
#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.
4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 |
# File 'lib/HDLRuby/hruby_high.rb', line 4603 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.
4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 |
# File 'lib/HDLRuby/hruby_high.rb', line 4640 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.
4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 |
# File 'lib/HDLRuby/hruby_high.rb', line 4625 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.
4589 4590 4591 4592 4593 4594 4595 4596 4597 |
# File 'lib/HDLRuby/hruby_high.rb', line 4589 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+.
1812 1813 1814 1815 1816 1817 |
# File 'lib/HDLRuby/hruby_high.rb', line 1812 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.
4564 4565 4566 4567 4568 4569 4570 4571 |
# File 'lib/HDLRuby/hruby_high.rb', line 4564 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.
4617 4618 4619 |
# File 'lib/HDLRuby/hruby_high.rb', line 4617 def self.in_behavior? top_user.is_a?(Block) end |
.in_system? ⇒ Boolean
Tells if within a system type.
4584 4585 4586 |
# File 'lib/HDLRuby/hruby_high.rb', line 4584 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.
4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 |
# File 'lib/HDLRuby/hruby_high.rb', line 4374 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.
4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 |
# File 'lib/HDLRuby/hruby_high.rb', line 4397 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.
5247 5248 5249 |
# File 'lib/HDLRuby/hruby_high.rb', line 5247 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.
5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 |
# File 'lib/HDLRuby/hruby_high.rb', line 5260 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.
5252 5253 5254 5255 5256 |
# File 'lib/HDLRuby/hruby_high.rb', line 5252 def self.names_has?(name) NameStack.find do |names| names.include?(name) end end |
.names_pop ⇒ Object
Pops from the name stack.
5242 5243 5244 |
# File 'lib/HDLRuby/hruby_high.rb', line 5242 def self.names_pop NameStack.pop end |
.names_push ⇒ Object
Pushes on the name stack.
5237 5238 5239 |
# File 'lib/HDLRuby/hruby_high.rb', line 5237 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
85 86 87 |
# File 'lib/HDLRuby/hruby_rcsim.rb', line 85 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+.
4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 |
# File 'lib/HDLRuby/hruby_high.rb', line 4673 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.
4576 4577 4578 4579 4580 4581 |
# File 'lib/HDLRuby/hruby_high.rb', line 4576 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.
4534 4535 4536 |
# File 'lib/HDLRuby/hruby_high.rb', line 4534 def self.space_include?(namespace) return Namespaces.include?(namespace) end |
.space_index(namespace) ⇒ Object
Gets the index of a +namespace+ within the stack.
4539 4540 4541 |
# File 'lib/HDLRuby/hruby_high.rb', line 4539 def self.space_index(namespace) return Namespaces.index(namespace) end |
.space_insert(index, namespace) ⇒ Object
Inserts +namespace+ at +index+.
4521 4522 4523 |
# File 'lib/HDLRuby/hruby_high.rb', line 4521 def self.space_insert(index,namespace) Namespaces.insert(index.to_i,namespace.to_namespace) end |
.space_pop ⇒ Object
Pops a namespace.
4526 4527 4528 4529 4530 4531 |
# File 'lib/HDLRuby/hruby_high.rb', line 4526 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+.
4513 4514 4515 4516 4517 4518 |
# File 'lib/HDLRuby/hruby_high.rb', line 4513 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.
4666 4667 4668 4669 |
# File 'lib/HDLRuby/hruby_high.rb', line 4666 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.
4544 4545 4546 |
# File 'lib/HDLRuby/hruby_high.rb', line 4544 def self.space_top Namespaces[-1] end |
.space_top=(top) ⇒ Object
sets the top namespace.
4549 4550 4551 4552 4553 4554 |
# File 'lib/HDLRuby/hruby_high.rb', line 4549 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.
4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 |
# File 'lib/HDLRuby/hruby_high.rb', line 4652 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.
4558 4559 4560 |
# File 'lib/HDLRuby/hruby_high.rb', line 4558 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.
2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 |
# File 'lib/HDLRuby/hruby_high.rb', line 2200 def function(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| # 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.
2186 2187 2188 2189 2190 2191 2192 2193 |
# File 'lib/HDLRuby/hruby_high.rb', line 2186 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.
3621 3622 3623 3624 3625 3626 3627 |
# File 'lib/HDLRuby/hruby_high.rb', line 3621 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+.
2127 2128 2129 |
# File 'lib/HDLRuby/hruby_high.rb', line 2127 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.
2173 2174 2175 2176 2177 2178 2179 |
# File 'lib/HDLRuby/hruby_high.rb', line 2173 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 |
#this ⇒ Object
Gives access to the this reference.
3631 3632 3633 3634 |
# File 'lib/HDLRuby/hruby_high.rb', line 3631 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.
2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 |
# File 'lib/HDLRuby/hruby_high.rb', line 2135 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 |