Class: HDLRuby::High::SystemT
- Inherits:
-
Low::SystemT
- Object
- Base::SystemT
- Low::SystemT
- HDLRuby::High::SystemT
- Includes:
- Hmissing, Hmux, SingletonExtend
- Defined in:
- lib/HDLRuby/hruby_high.rb
Overview
Describes a high-level system type.
Constant Summary collapse
Constants included from Hmissing
Constants included from Low::Low2Symbol
Low::Low2Symbol::Low2SymbolPrefix, Low::Low2Symbol::Low2SymbolTable, Low::Low2Symbol::Symbol2LowTable
Instance Attribute Summary collapse
-
#instance_class ⇒ Object
readonly
The instantiation target class.
-
#public_namespace ⇒ Object
readonly
The public namespace.
Attributes inherited from Low::SystemT
Attributes included from Low::Hparent
Instance Method Summary collapse
-
#add_generator(gen) ⇒ Object
Adds a generator system.
-
#as(system) ⇒ Object
Casts as an included +system+.
-
#each_export(&ruby_block) ⇒ Object
Iterates over the exported constructs.
-
#each_generator(&ruby_block) ⇒ Object
Iterates over the origin systems.
-
#each_instance_proc(&ruby_block) ⇒ Object
Iterates over the instance procedures.
-
#each_on_instance(&ruby_block) ⇒ Object
Iterate over the task to apply on the instances of the system.
-
#each_signal_with_included(&ruby_block) ⇒ Object
Iterates over the all interface signals, i.e, also the ones of the included systems.
-
#eigenize(instance) ⇒ Object
Make a system eigen of a given +instance+.
-
#expand(name, *args) ⇒ Object
Expands the system with possible arugments +args+ to a new system named +name+.
-
#extend(system) ⇒ Object
Extend the class according to another +system+.
-
#fill_interface(systemTlow) ⇒ Object
Fills the interface of a low level system.
-
#fill_low(systemTlow) ⇒ Object
Fills a low level system with self's contents.
-
#get_interface_with_included(i) ⇒ Object
Get one of all the interface signal by index, i.e., also the ones of the included systems.
-
#get_output_with_included(name) ⇒ Object
Gets an output signal by +name+ considering also the included systems.
-
#initialize(name, *mixins, &ruby_block) ⇒ SystemT
constructor
Creates a new high-level system type named +name+ and inheriting from +mixins+.
-
#inout(*names) ⇒ Object
Declares high-level bit inout signals named +names+.
-
#input(*names) ⇒ Object
Declares high-level bit input signals named +names+.
-
#instantiate(i_name, *args) ⇒ Object
(also: #call)
Instantiate the system type to an instance named +i_name+ with possible arguments +args+.
-
#make_inouts(type, *names) ⇒ Object
Creates and adds a set of inouts typed +type+ from a list of +names+.
-
#make_inputs(type, *names) ⇒ Object
Creates and adds a set of inputs typed +type+ from a list of +names+.
-
#make_instantiater(name, klass, &ruby_block) ⇒ Object
Generates the instantiation capabilities including an instantiation method +name+ for hdl-like instantiation, target instantiation as +klass+, added to the calling object, and whose eigen type is initialized by +ruby_block+.
-
#make_outputs(type, *names) ⇒ Object
Creates and adds a set of outputs typed +type+ from a list of +names+.
-
#namespace ⇒ Object
Gets the private namespace of the system.
-
#of?(system) ⇒ Boolean
Tell if the current system is a descedent of +system+.
-
#on_instance(&ruby_block) ⇒ Object
Adds a task to apply on the instances of the system.
-
#open(&ruby_block) ⇒ Object
Opens for extension.
-
#output(*names) ⇒ Object
Declares high-level bit output signals named +names+.
-
#run(&ruby_block) ⇒ Object
Execute +ruby_block+ in the context of the system.
-
#singleton_instance ⇒ Object
Gets class containing the extension for the instances.
-
#to_low(name = self.name) ⇒ Object
Converts the system to HDLRuby::Low and set its +name+.
-
#to_user ⇒ Object
Converts to a namespace user.
Methods included from Hmux
Methods included from Hmissing
Methods included from SingletonExtend
Methods inherited from Low::SystemT
#add_inout, #add_input, #add_output, #bit2vector2inner!, #blocks2seq!, #boolean_in_assign2select!, #break_concat_assigns!, #break_types!, #c_code_allocate, #casts_without_expression!, #cleanup!, #connections_to_behaviors!, #delete_inout!, #delete_input!, #delete_output!, #each_deep, #each_inout, #each_input, #each_output, #each_signal, #each_signal_all, #each_signal_deep, #each_systemT_deep, #each_systemT_deep_ref, #eql?, #explicit_types!, #extract_port_assign!, get, #get_all_inouts, #get_all_inputs, #get_all_outputs, #get_all_signals, #get_by_name, #get_inout, #get_input, #get_interface, #get_output, #get_signal, #has_inout?, #has_input?, #has_output?, #has_signal?, #hash, #initial_concat_to_timed!, #map_inouts!, #map_inputs!, #map_outputs!, #mixblocks2seq!, #outread2inner!, #par_in_seq2seq!, #port_assign?, #port_output_connection?, #replace_names!, #select2case!, #set_name!, #set_scope!, #to_c, #to_c_code, #to_ch, #to_global_systemTs!, #to_hdr, #to_high, #to_upper_space!, #to_verilog, #to_vhdl, #with_boolean!, #with_port!, #with_var!, #wrapper, #wrapper=
Methods included from Low::ForceName
Methods included from Low::Low2Symbol
Methods included from Low::Hparent
Constructor Details
#initialize(name, *mixins, &ruby_block) ⇒ SystemT
Creates a new high-level system type named +name+ and inheriting from +mixins+.
If name is hash, it is considered the system is unnamed and the
table is used to rename its signals or instances.
The proc +ruby_block+ is executed when instantiating the system.
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
# File 'lib/HDLRuby/hruby_high.rb', line 344 def initialize(name, *mixins, &ruby_block) # Initialize the system type structure. super(name,Scope.new(name,self)) # puts "new systemT=#{self}" # Initialize the set of extensions to transmit to the instances' # eigen class @singleton_instanceO = Namespace.new(self.scope) # Create the public namespace. @public_namespace = Namespace.new(self.scope) # Initialize the list of tasks to execute on the instance. @on_instances = [] # Check and set the mixins. mixins.each do |mixin| unless mixin.is_a?(SystemT) then raise AnyError, "Invalid class for inheriting: #{mixin.class}." end end @to_includes = mixins # The list of systems the current system is expanded from if any. # The first one is the main system, the other ones are the # mixins. @generators = [] # Prepare the instantiation methods make_instantiater(name,SystemI,&ruby_block) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class HDLRuby::High::Hmissing
Instance Attribute Details
#instance_class ⇒ Object (readonly)
The instantiation target class.
572 573 574 |
# File 'lib/HDLRuby/hruby_high.rb', line 572 def instance_class @instance_class end |
#public_namespace ⇒ Object (readonly)
The public namespace
NOTE: the private namespace is the namespace of the scope object.
334 335 336 |
# File 'lib/HDLRuby/hruby_high.rb', line 334 def public_namespace @public_namespace end |
Instance Method Details
#add_generator(gen) ⇒ Object
Adds a generator system.
521 522 523 524 525 526 |
# File 'lib/HDLRuby/hruby_high.rb', line 521 def add_generator(gen) unless gen.is_a?(SystemT) then raise "Invalid class for a generator system" end @generators << gen end |
#as(system) ⇒ Object
Casts as an included +system+.
NOTE: use the includes of the scope.
768 769 770 771 |
# File 'lib/HDLRuby/hruby_high.rb', line 768 def as(system) # return self.scope.as(system.scope) return self.scope.as(system) end |
#each_export(&ruby_block) ⇒ Object
Iterates over the exported constructs
NOTE: look into the scope.
516 517 518 |
# File 'lib/HDLRuby/hruby_high.rb', line 516 def each_export(&ruby_block) @scope.each_export(&ruby_block) end |
#each_generator(&ruby_block) ⇒ Object
Iterates over the origin systems.
Returns an enumerator if no ruby block is given.
531 532 533 534 535 536 |
# File 'lib/HDLRuby/hruby_high.rb', line 531 def each_generator(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_generator) unless ruby_block # A block? Apply it on each generator. @generators.each(&ruby_block) end |
#each_instance_proc(&ruby_block) ⇒ Object
Iterates over the instance procedures.
Returns an enumerator if no ruby block is given.
577 578 579 580 581 582 |
# File 'lib/HDLRuby/hruby_high.rb', line 577 def each_instance_proc(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_instance_proc) unless ruby_block # A block? Apply it on each input signal instance. @instance_procs.each(&ruby_block) end |
#each_on_instance(&ruby_block) ⇒ Object
Iterate over the task to apply on the instances of the system.
644 645 646 647 648 649 |
# File 'lib/HDLRuby/hruby_high.rb', line 644 def each_on_instance(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_on_instance) unless ruby_block # A block? Apply it on each overload if any. @on_instances.each(&ruby_block) end |
#each_signal_with_included(&ruby_block) ⇒ Object
Iterates over the all interface signals, i.e, also the ones of the included systems.
Returns an enumerator if no ruby block is given.
496 497 498 499 500 501 502 503 504 505 |
# File 'lib/HDLRuby/hruby_high.rb', line 496 def each_signal_with_included(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_signal_with_included) unless ruby_block # Iterate on the signals of the current system. self.each_signal(&ruby_block) # Recurse on the included systems. self.scope.each_included do |included| included.each_signal_with_included(&ruby_block) end end |
#eigenize(instance) ⇒ Object
Make a system eigen of a given +instance+.
610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 |
# File 'lib/HDLRuby/hruby_high.rb', line 610 def eigenize(instance) unless instance.systemT == self then raise "Cannot eigenize system #{self.name} to instance #{instance.name}" end # The instance becames the owner. @owner = instance # Fill the public namespace space = self.public_namespace # Interface signals # puts "i_name=#{i_name} @to_includes=#{@to_includes.size}" self.each_signal do |signal| # puts "signal=#{signal.name}" space.send(:define_singleton_method,signal.name) do RefObject.new(instance.to_ref,signal) end end # Exported objects self.each_export do |export| # puts "export=#{export.name}" space.send(:define_singleton_method,export.name) do RefObject.new(instance.to_ref,export) end end return self end |
#expand(name, *args) ⇒ Object
Expands the system with possible arugments +args+ to a new system named +name+.
586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 |
# File 'lib/HDLRuby/hruby_high.rb', line 586 def (name, *args) # puts "expand #{self.name} to #{name}" # Create the new system. = self.class.new(name.to_s) {} # Include the mixin systems given when declaring the system. @to_includes.each { |system| .scope.include(system) } # Include the previously includeds. */ self.scope.each_included { |system| .scope.include(system) } # Sets the generators of the expanded result. .add_generator(self) # puts "expanded=#{expanded}" @to_includes.each { |system| .add_generator(system) } # Also for the previously includeds. */ self.scope.each_included.each { |system| .add_generator(system) } # Fills the scope of the expanded class. # puts "Build top with #{self.name} for #{name}" .scope.build_top(self.scope,*args) # puts "Top built with #{self.name} for #{name}" return end |
#extend(system) ⇒ Object
Extend the class according to another +system+.
758 759 760 761 762 763 |
# File 'lib/HDLRuby/hruby_high.rb', line 758 def extend(system) # Adds the singleton methods self.eigen_extend(system) # Adds the singleton methods for the instances. @singleton_instanceO.eigen_extend(system.singleton_instance) end |
#fill_interface(systemTlow) ⇒ Object
Fills the interface of a low level system.
776 777 778 779 780 781 782 783 784 785 786 787 |
# File 'lib/HDLRuby/hruby_high.rb', line 776 def fill_interface(systemTlow) # Adds its input signals. self.each_input { |input| systemTlow.add_input(input.to_low) } # Adds its output signals. self.each_output { |output| systemTlow.add_output(output.to_low) } # Adds its inout signals. self.each_inout { |inout| systemTlow.add_inout(inout.to_low) } # Adds the interface of its included systems. self.scope.each_included do |included| included.fill_interface(systemTlow) end end |
#fill_low(systemTlow) ⇒ Object
Fills a low level system with self's contents.
NOTE: name conflicts are treated in the current NameStack state.
792 793 794 795 |
# File 'lib/HDLRuby/hruby_high.rb', line 792 def fill_low(systemTlow) # Fills the interface self.fill_interface(systemTlow) end |
#get_interface_with_included(i) ⇒ Object
Get one of all the interface signal by index, i.e., also the ones of the included systems.
509 510 511 |
# File 'lib/HDLRuby/hruby_high.rb', line 509 def get_interface_with_included(i) return each_signal_with_included.to_a[i] end |
#get_output_with_included(name) ⇒ Object
Gets an output signal by +name+ considering also the included systems
479 480 481 482 483 484 485 486 487 488 489 490 |
# File 'lib/HDLRuby/hruby_high.rb', line 479 def get_output_with_included(name) # Look in self. found = self.get_output(name) return found if found # Not in self, look in the included systems. self.scope.each_included do |included| found = included.get_output_with_included(name) return found if found end # Not found return nil end |
#inout(*names) ⇒ Object
Declares high-level bit inout signals named +names+.
Retuns the last declared input.
753 754 755 |
# File 'lib/HDLRuby/hruby_high.rb', line 753 def inout(*names) self.make_inouts(bit,*names) end |
#input(*names) ⇒ Object
Declares high-level bit input signals named +names+.
Retuns the last declared input.
739 740 741 |
# File 'lib/HDLRuby/hruby_high.rb', line 739 def input(*names) self.make_inputs(bit,*names) end |
#instantiate(i_name, *args) ⇒ Object Also known as: call
Instantiate the system type to an instance named +i_name+ with possible arguments +args+.
654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 |
# File 'lib/HDLRuby/hruby_high.rb', line 654 def instantiate(i_name,*args) # Create the eigen type. # eigen = self.expand(High.names_create(i_name.to_s + ":T"), *args) eigen = self.(HDLRuby.uniq_name(i_name.to_s + ":T"), *args) # Create the instance and sets its eigen system to +eigen+. instance = @instance_class.new(i_name,eigen) # puts "instance=#{instance}" eigen.eigenize(instance) # Extend the instance. instance.eigen_extend(@singleton_instanceO) # puts "instance scope= #{instance.systemT.scope}" # Add the instance if instantiating within another system. High.top_user.send(:add_systemI,instance) if High.top_user # Execute the post instantiation tasks. eigen.each_on_instance { |task| task.(instance) } # Return the resulting instance return instance end |
#make_inouts(type, *names) ⇒ Object
Creates and adds a set of inouts typed +type+ from a list of +names+.
NOTE: a name can also be a signal, is which case it is duplicated.
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 |
# File 'lib/HDLRuby/hruby_high.rb', line 458 def make_inouts(type, *names) res = nil names.each do |name| if name.respond_to?(:to_sym) then res = self.add_inout(SignalI.new(name,type,:inout)) elsif name.is_a?(Hash) then # Names associated with values. names.each do |name,value| res = self.add_inner( SignalI.new(name,type,:inner,value)) end else raise AnyError, "Invalid class for a name: #{name.class}" end end return res end |
#make_inputs(type, *names) ⇒ Object
Creates and adds a set of inputs typed +type+ from a list of +names+.
NOTE: a name can also be a signal, is which case it is duplicated.
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 |
# File 'lib/HDLRuby/hruby_high.rb', line 408 def make_inputs(type, *names) # Check if called within the top scope of the block. if High.top_user != @scope then # No, cannot make an input from here. raise AnyError, "Input signals can only be declared in the top scope of a system." end res = nil names.each do |name| if name.respond_to?(:to_sym) then res = self.add_input(SignalI.new(name,type,:input)) elsif name.is_a?(Hash) then # Names associated with values. names.each do |name,value| res = self.add_inner( SignalI.new(name,type,:inner,value)) end else raise AnyError, "Invalid class for a name: #{name.class}" end end return res end |
#make_instantiater(name, klass, &ruby_block) ⇒ Object
Generates the instantiation capabilities including an instantiation method +name+ for hdl-like instantiation, target instantiation as +klass+, added to the calling object, and whose eigen type is initialized by +ruby_block+.
NOTE: actually creates two instantiater, a general one, being registered in the namespace stack, and one for creating an array of instances being registered in the Array class.
688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 |
# File 'lib/HDLRuby/hruby_high.rb', line 688 def make_instantiater(name,klass,&ruby_block) # puts "make_instantiater with name=#{name}" # Set the instanciater. @instance_procs = [ ruby_block ] # Set the target instantiation class. @instance_class = klass # Unnamed types do not have associated access method. return if name.empty? obj = self # For using the right self within the proc # Create and register the general instantiater. High.space_reg(name) do |*args| # puts "Instantiating #{name} with args=#{args.size}" # If no arguments, return the system as is return obj if args.empty? # Are there any generic arguments? if ruby_block.arity > 0 then # Yes, must specialize the system with the arguments. # If arguments, create a new system specialized with them return SystemT.new(:"") { include(obj,*args) } end # It is the case where it is an instantiation # Get the names from the arguments. i_names = args.shift # puts "i_names=#{i_names}(#{i_names.class})" i_names = [*i_names] instance = nil # The current instance i_names.each do |i_name| # Instantiate. instance = obj.instantiate(i_name,*args) end # # Return the last instance. instance end # Create and register the array of instances instantiater. ::Array.class_eval do define_method(name) { |*args| make(name,*args) } end end |
#make_outputs(type, *names) ⇒ Object
Creates and adds a set of outputs typed +type+ from a list of +names+.
NOTE: a name can also be a signal, is which case it is duplicated.
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 |
# File 'lib/HDLRuby/hruby_high.rb', line 435 def make_outputs(type, *names) # puts "type=#{type.inspect}" res = nil names.each do |name| # puts "name=#{name}" if name.respond_to?(:to_sym) then res = self.add_output(SignalI.new(name,type,:output)) elsif name.is_a?(Hash) then # Names associated with values. names.each do |name,value| res = self.add_inner( SignalI.new(name,type,:inner,value)) end else raise AnyError, "Invalid class for a name: #{name.class}" end end return res end |
#namespace ⇒ Object
Gets the private namespace of the system.
544 545 546 |
# File 'lib/HDLRuby/hruby_high.rb', line 544 def namespace return self.scope.namespace end |
#of?(system) ⇒ Boolean
Tell if the current system is a descedent of +system+
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 |
# File 'lib/HDLRuby/hruby_high.rb', line 379 def of?(system) # Maybe self is system. if (self == system) then # Yes, consider it is adescendent of system. return true else # Look into the generators. @generators.each do |generator| return true if generator.of?(system) end # Look into the included systems. @to_includes.each do |included| return true if included.of?(system) end end # Not found. return false end |
#on_instance(&ruby_block) ⇒ Object
Adds a task to apply on the instances of the system.
639 640 641 |
# File 'lib/HDLRuby/hruby_high.rb', line 639 def on_instance(&ruby_block) @on_instances << ruby_block end |
#open(&ruby_block) ⇒ Object
Opens for extension.
NOTE: actually executes +ruby_block+ in the context of the scope of the system.
557 558 559 560 561 562 563 564 565 566 567 568 569 |
# File 'lib/HDLRuby/hruby_high.rb', line 557 def open(&ruby_block) # Are we instantiating current system? if (High.space_include?(self.scope.namespace)) then # Yes, execute the ruby block in the top context of the # system. # self.scope.open(&ruby_block) self.run(&ruby_block) else # No, add the ruby block to the list of block to execute # when instantiating. @instance_procs << ruby_block end end |
#output(*names) ⇒ Object
Declares high-level bit output signals named +names+.
Retuns the last declared input.
746 747 748 |
# File 'lib/HDLRuby/hruby_high.rb', line 746 def output(*names) self.make_outputs(bit,*names) end |
#run(&ruby_block) ⇒ Object
Execute +ruby_block+ in the context of the system.
549 550 551 |
# File 'lib/HDLRuby/hruby_high.rb', line 549 def run(&ruby_block) self.scope.open(&ruby_block) end |
#singleton_instance ⇒ Object
Gets class containing the extension for the instances.
539 540 541 |
# File 'lib/HDLRuby/hruby_high.rb', line 539 def singleton_instance @singleton_instanceO.singleton_class end |
#to_low(name = self.name) ⇒ Object
Converts the system to HDLRuby::Low and set its +name+.
798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 |
# File 'lib/HDLRuby/hruby_high.rb', line 798 def to_low(name = self.name) name = name.to_s if name.empty? then raise AnyError, "Cannot convert a system without a name to HDLRuby::Low." end # Create the resulting low system type. # systemTL = HDLRuby::Low::SystemT.new(High.names_create(name), systemTL = HDLRuby::Low::SystemT.new(HDLRuby.uniq_name(name), self.scope.to_low) # puts "New low from system #{self.name}: #{systemTL.name}" # # For debugging: set the source high object # systemTL.properties[:low2high] = self.hdr_id # self.properties[:high2low] = systemTL # Fills the interface of the new system # from the included systems. self.fill_low(systemTL) # Return theresulting system. return systemTL end |
#to_user ⇒ Object
Converts to a namespace user.
400 401 402 403 |
# File 'lib/HDLRuby/hruby_high.rb', line 400 def to_user # Returns the scope. return @scope end |