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, RefConcat, RefIndex, RefName, RefObject, RefRange, RefThis, Scope, Select, SignalC, SignalI, 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)
- 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.
-
#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.
3747 3748 3749 |
# File 'lib/HDLRuby/hruby_high.rb', line 3747 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.
3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 |
# File 'lib/HDLRuby/hruby_high.rb', line 3775 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.
3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 |
# File 'lib/HDLRuby/hruby_high.rb', line 3760 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.
3733 3734 3735 3736 3737 3738 3739 3740 3741 |
# File 'lib/HDLRuby/hruby_high.rb', line 3733 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+.
1519 1520 1521 1522 1523 1524 |
# File 'lib/HDLRuby/hruby_high.rb', line 1519 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.
3708 3709 3710 3711 3712 3713 3714 3715 |
# File 'lib/HDLRuby/hruby_high.rb', line 3708 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.
3752 3753 3754 |
# File 'lib/HDLRuby/hruby_high.rb', line 3752 def self.in_behavior? top_user.is_a?(Block) end |
.in_system? ⇒ Boolean
Tells if within a system type.
3728 3729 3730 |
# File 'lib/HDLRuby/hruby_high.rb', line 3728 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.
3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 |
# File 'lib/HDLRuby/hruby_high.rb', line 3524 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.
3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 |
# File 'lib/HDLRuby/hruby_high.rb', line 3547 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.
4323 4324 4325 |
# File 'lib/HDLRuby/hruby_high.rb', line 4323 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.
4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 |
# File 'lib/HDLRuby/hruby_high.rb', line 4336 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.
4328 4329 4330 4331 4332 |
# File 'lib/HDLRuby/hruby_high.rb', line 4328 def self.names_has?(name) NameStack.find do |names| names.include?(name) end end |
.names_pop ⇒ Object
Pops from the name stack.
4318 4319 4320 |
# File 'lib/HDLRuby/hruby_high.rb', line 4318 def self.names_pop NameStack.pop end |
.names_push ⇒ Object
Pushes on the name stack.
4313 4314 4315 |
# File 'lib/HDLRuby/hruby_high.rb', line 4313 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+.
3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 |
# File 'lib/HDLRuby/hruby_high.rb', line 3808 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.
3720 3721 3722 3723 3724 3725 |
# File 'lib/HDLRuby/hruby_high.rb', line 3720 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.
3678 3679 3680 |
# File 'lib/HDLRuby/hruby_high.rb', line 3678 def self.space_include?(namespace) return Namespaces.include?(namespace) end |
.space_index(namespace) ⇒ Object
Gets the index of a +namespace+ within the stack.
3683 3684 3685 |
# File 'lib/HDLRuby/hruby_high.rb', line 3683 def self.space_index(namespace) return Namespaces.index(namespace) end |
.space_insert(index, namespace) ⇒ Object
Inserts +namespace+ at +index+.
3665 3666 3667 |
# File 'lib/HDLRuby/hruby_high.rb', line 3665 def self.space_insert(index,namespace) Namespaces.insert(index.to_i,namespace.to_namespace) end |
.space_pop ⇒ Object
Pops a namespace.
3670 3671 3672 3673 3674 3675 |
# File 'lib/HDLRuby/hruby_high.rb', line 3670 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+.
3657 3658 3659 3660 3661 3662 |
# File 'lib/HDLRuby/hruby_high.rb', line 3657 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.
3801 3802 3803 3804 |
# File 'lib/HDLRuby/hruby_high.rb', line 3801 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.
3688 3689 3690 |
# File 'lib/HDLRuby/hruby_high.rb', line 3688 def self.space_top Namespaces[-1] end |
.space_top=(top) ⇒ Object
sets the top namespace.
3693 3694 3695 3696 3697 3698 |
# File 'lib/HDLRuby/hruby_high.rb', line 3693 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.
3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 |
# File 'lib/HDLRuby/hruby_high.rb', line 3787 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.
3702 3703 3704 |
# File 'lib/HDLRuby/hruby_high.rb', line 3702 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.
1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 |
# File 'lib/HDLRuby/hruby_high.rb', line 1859 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 |
#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.
1847 1848 1849 1850 1851 1852 |
# File 'lib/HDLRuby/hruby_high.rb', line 1847 def instance(name, *includes, &ruby_block) # Creates the system type. systemT = system(:"",*includes,&ruby_block) # Instantiate it with +name+. return systemT.instantiate(name) end |
#struct(content) ⇒ Object
Creates an unnamed structure type from a +content+.
1793 1794 1795 |
# File 'lib/HDLRuby/hruby_high.rb', line 1793 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.
1836 1837 1838 1839 1840 |
# File 'lib/HDLRuby/hruby_high.rb', line 1836 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.
2929 2930 2931 |
# File 'lib/HDLRuby/hruby_high.rb', line 2929 def this RefThis.new end |
#typedef(name, &ruby_block) ⇒ Object
Declares a high-level generic type named +name+, and using +ruby_block+ for construction.
1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 |
# File 'lib/HDLRuby/hruby_high.rb', line 1801 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 |