Class: HDLRuby::High::SystemT
- Inherits:
-
Low::SystemT
- Object
- Low::SystemT
- HDLRuby::High::SystemT
- Includes:
- Hmissing, Hmux, SingletonExtend
- Defined in:
- lib/HDLRuby/hruby_high.rb,
lib/HDLRuby/hruby_rsim.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
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.
-
#multithread ⇒ Object
readonly
Tell if the simulation is in multithread mode or not.
-
#public_namespace ⇒ Object
readonly
The public namespace.
-
#rcsystemT ⇒ Object
readonly
Extends the SystemT class for hybrid Ruby-C simulation.
-
#time ⇒ Object
readonly
The current global time.
Attributes inherited from Low::SystemT
Attributes included from Low::Hparent
Instance Method Summary collapse
-
#add_generator(gen) ⇒ Object
Adds a generator system.
-
#add_sig_active(sig) ⇒ Object
Add +sig+ to the list of active signals.
-
#add_timed_behavior(beh) ⇒ Object
Add timed behavior +beh+.
-
#add_untimed(obj) ⇒ Object
Add untimed objet +obj+.
-
#advance ⇒ Object
Advance the global simulator.
-
#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_all_with_included(&ruby_block) ⇒ Object
Iterates over the all signals (input, output, inout, inner, constant), i.e, also the ones of the included systems.
-
#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_low(systemTlow) ⇒ Object
Fills the interface of a low level system.
-
#fill_low(systemTlow) ⇒ Object
Fills a low level system with self's contents.
-
#fullname ⇒ Object
Returns the name of the signal with its hierarchy.
-
#get_inout_with_included(name) ⇒ Object
Gets an inout signal by +name+ considering also the included systems.
-
#get_input_with_included(name) ⇒ Object
Gets an input signal by +name+ considering also the included systems.
-
#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.
-
#get_signal_with_included(name) ⇒ Object
Gets a signal by +name+ considering also the included systems.
-
#get_vars_with_fullname(vars_with_fullname = {}) ⇒ Object
Gets the VCD variables with their long name.
-
#get_vars_with_idstr(vars_with_idstr = {}) ⇒ Object
Gets the VCD variables with their id string.
-
#init_sim(systemT) ⇒ Object
Initialize the simulation for system +systemT+.
-
#init_untimeds ⇒ Object
Initialize the untimed objects.
-
#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+.
-
#merge_included! ⇒ Object
Merge the included systems interface in current system.
-
#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+.
-
#remove_timed_behavior(beh) ⇒ Object
Remove timed beahvior +beh+.
-
#run(&ruby_block) ⇒ Object
Execute +ruby_block+ in the context of the system.
-
#run_ack ⇒ Object
Acknowledge the run request the executable timed behavior.
-
#run_done(id) ⇒ Object
Tell running part done for timed behavior +id+.
-
#run_init(&ruby_block) ⇒ Object
Initialize run for executing +ruby_block+.
-
#run_req(id) ⇒ Object
Request for running for timed behavior +id+.
-
#run_wait ⇒ Object
Wait for all the run to complete.
-
#show_hierarchy(vcdout) ⇒ Object
Shows the hierarchy of the variables.
-
#show_init(vcdout) ⇒ Object
Initializes the displayer for generating a vcd on +vcdout+.
-
#show_signal(sig) ⇒ Object
Displays the value of signal +sig+.
-
#show_string(str) ⇒ Object
Displays string +str+.
-
#show_time ⇒ Object
Displays the time.
-
#show_value(val) ⇒ Object
Displays value +val+.
-
#sim(simout) ⇒ Object
Run the simulation from the current systemT and outputs the resuts on simout.
-
#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_rcsim(rcowner = nil) ⇒ Object
Generate the C description of the systemT.
-
#to_ref ⇒ Object
Converts to a new reference.
-
#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!, decompose_vec2d?, #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_all_inouts, #get_all_inputs, #get_all_outputs, #get_all_signals, #get_by_name, get_indirect_verilog_regs, #get_inout, #get_input, #get_interface, #get_output, get_regs, #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!, #signal2subs!, #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
#absolute_ref, #hierarchy, #no_parent!, #scope
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.
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 |
# File 'lib/HDLRuby/hruby_high.rb', line 353 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.
639 640 641 |
# File 'lib/HDLRuby/hruby_high.rb', line 639 def instance_class @instance_class end |
#multithread ⇒ Object (readonly)
Tell if the simulation is in multithread mode or not.
21 22 23 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 21 def multithread @multithread end |
#public_namespace ⇒ Object (readonly)
The public namespace
NOTE: the private namespace is the namespace of the scope object.
343 344 345 |
# File 'lib/HDLRuby/hruby_high.rb', line 343 def public_namespace @public_namespace end |
#rcsystemT ⇒ Object (readonly)
Extends the SystemT class for hybrid Ruby-C simulation.
96 97 98 |
# File 'lib/HDLRuby/hruby_rcsim.rb', line 96 def rcsystemT @rcsystemT end |
#time ⇒ Object (readonly)
The current global time.
24 25 26 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 24 def time @time end |
Instance Method Details
#add_generator(gen) ⇒ Object
Adds a generator system.
588 589 590 591 592 593 |
# File 'lib/HDLRuby/hruby_high.rb', line 588 def add_generator(gen) unless gen.is_a?(SystemT) then raise "Invalid class for a generator system" end @generators << gen end |
#add_sig_active(sig) ⇒ Object
Add +sig+ to the list of active signals.
46 47 48 49 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 46 def add_sig_active(sig) # puts "Adding activated signal=#{sig.fullname}" @sig_active << sig end |
#add_timed_behavior(beh) ⇒ Object
Add timed behavior +beh+. Returns the id of the timed behavior.
33 34 35 36 37 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 33 def add_timed_behavior(beh) @timed_behaviors << beh @total_timed_behaviors += 1 return @total_timed_behaviors - 1 end |
#add_untimed(obj) ⇒ Object
Add untimed objet +obj+
27 28 29 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 27 def add_untimed(obj) @untimeds << obj end |
#advance ⇒ Object
Advance the global simulator.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 52 def advance # # Display the time # self.show_time shown_values = {} # Get the behaviors waiting on activated signals. until @sig_active.empty? do # puts "sig_active.size=#{@sig_active.size}" # puts "sig_active=#{@sig_active.map {|sig| sig.fullname}}" # Look for the behavior sensitive to the signals. # @sig_active.each do |sig| # sig.each_anyedge { |beh| @sig_exec << beh } # if (sig.c_value.zero? && !sig.f_value.zero?) then # # puts "sig.c_value=#{sig.c_value.content}" # sig.each_posedge { |beh| @sig_exec << beh } # elsif (!sig.c_value.zero? && sig.f_value.zero?) then # sig.each_negedge { |beh| @sig_exec << beh } # end # end @sig_active.each do |sig| next if (sig.c_value.eql?(sig.f_value)) # next if (sig.c_value.to_vstr == sig.f_value.to_vstr) # puts "for sig=#{sig.fullname}" sig.each_anyedge { |beh| @sig_exec << beh } if (sig.c_value.zero?) then # puts "sig.c_value=#{sig.c_value.content}" sig.each_posedge { |beh| @sig_exec << beh } elsif (!sig.c_value.zero?) then sig.each_negedge { |beh| @sig_exec << beh } end end # Update the signals. @sig_active.each { |sig| sig.c_value = sig.f_value } # puts "first @sig_exec.size=#{@sig_exec.size}" @sig_exec.uniq! {|beh| beh.object_id } # puts "now @sig_exec.size=#{@sig_exec.size}" # Display the activated signals. @sig_active.each do |sig| if !shown_values[sig].eql?(sig.f_value) then self.show_signal(sig) shown_values[sig] = sig.f_value end end # Clear the list of active signals. @sig_active.clear # puts "sig_exec.size=#{@sig_exec.size}" # Execute the relevant behaviors and connections. @sig_exec.each { |obj| obj.execute(:par) } @sig_exec.clear @sig_active.uniq! {|sig| sig.object_id } # puts "@sig_active.size=#{@sig_active.size}" # Compute the nearest next time stamp. @time = (@timed_behaviors.min {|b0,b1| b0.time <=> b1.time }).time end # puts "@time=#{@time}" # Display the time self.show_time end |
#as(system) ⇒ Object
Casts as an included +system+.
NOTE: use the includes of the scope.
834 835 836 837 |
# File 'lib/HDLRuby/hruby_high.rb', line 834 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.
583 584 585 |
# File 'lib/HDLRuby/hruby_high.rb', line 583 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.
598 599 600 601 602 603 |
# File 'lib/HDLRuby/hruby_high.rb', line 598 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.
644 645 646 647 648 649 |
# File 'lib/HDLRuby/hruby_high.rb', line 644 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.
710 711 712 713 714 715 |
# File 'lib/HDLRuby/hruby_high.rb', line 710 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_all_with_included(&ruby_block) ⇒ Object
Iterates over the all signals (input, output, inout, inner, constant), i.e, also the ones of the included systems.
Returns an enumerator if no ruby block is given.
540 541 542 543 544 545 546 547 548 549 |
# File 'lib/HDLRuby/hruby_high.rb', line 540 def each_signal_all_with_included(&ruby_block) # No ruby block? Return an enumerator. return to_enum(:each_signal_all_with_included) unless ruby_block # Iterate on all the signals of the current system. self.each_signal_all(&ruby_block) # Recurse on the included systems. self.scope.each_included do |included| included.each_signal_all_with_included(&ruby_block) end 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.
555 556 557 558 559 560 561 562 563 564 |
# File 'lib/HDLRuby/hruby_high.rb', line 555 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 all 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+.
677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 |
# File 'lib/HDLRuby/hruby_high.rb', line 677 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 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+.
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 |
# File 'lib/HDLRuby/hruby_high.rb', line 653 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+.
824 825 826 827 828 829 |
# File 'lib/HDLRuby/hruby_high.rb', line 824 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_low(systemTlow) ⇒ Object
Fills the interface of a low level system.
854 855 856 857 858 859 860 861 862 863 864 865 |
# File 'lib/HDLRuby/hruby_high.rb', line 854 def fill_interface_low(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_low(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.
870 871 872 873 |
# File 'lib/HDLRuby/hruby_high.rb', line 870 def fill_low(systemTlow) # Fills the interface self.fill_interface_low(systemTlow) end |
#fullname ⇒ Object
Returns the name of the signal with its hierarchy.
324 325 326 327 328 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 324 def fullname @fullname ||= (self.parent ? self.parent.fullname + ":" : "") + self.name.to_s return @fullname end |
#get_inout_with_included(name) ⇒ Object
Gets an inout signal by +name+ considering also the included systems
523 524 525 526 527 528 529 530 531 532 533 534 |
# File 'lib/HDLRuby/hruby_high.rb', line 523 def get_inout_with_included(name) # Look in self. found = self.get_inout(name) return found if found # Not in self, look in the included systems. self.scope.each_included do |included| found = included.get_inout_with_included(name) return found if found end # Not found return nil end |
#get_input_with_included(name) ⇒ Object
Gets an input signal by +name+ considering also the included systems
493 494 495 496 497 498 499 500 501 502 503 504 |
# File 'lib/HDLRuby/hruby_high.rb', line 493 def get_input_with_included(name) # Look in self. found = self.get_input(name) return found if found # Not in self, look in the included systems. self.scope.each_included do |included| found = included.get_input_with_included(name) return found if found end # Not found return nil 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.
568 569 570 |
# File 'lib/HDLRuby/hruby_high.rb', line 568 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
508 509 510 511 512 513 514 515 516 517 518 519 |
# File 'lib/HDLRuby/hruby_high.rb', line 508 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 |
#get_signal_with_included(name) ⇒ Object
Gets a signal by +name+ considering also the included systems
574 575 576 577 578 |
# File 'lib/HDLRuby/hruby_high.rb', line 574 def get_signal_with_included(name) return get_input_with_included(name) || get_output_with_included(name) || get_inout_with_included(name) end |
#get_vars_with_fullname(vars_with_fullname = {}) ⇒ Object
Gets the VCD variables with their long name.
96 97 98 99 100 101 102 103 104 |
# File 'lib/HDLRuby/hruby_rsim_vcd.rb', line 96 def get_vars_with_fullname(vars_with_fullname = {}) # Recurse on the signals. self.each_signal do |sig| sig.get_vars_with_fullname(vars_with_fullname) # vars_with_fullname[sig] = HDLRuby::High.vcd_name(sig.fullname) end # Recurse on the scope. return self.scope.get_vars_with_fullname(vars_with_fullname) end |
#get_vars_with_idstr(vars_with_idstr = {}) ⇒ Object
Gets the VCD variables with their id string.
107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/HDLRuby/hruby_rsim_vcd.rb', line 107 def get_vars_with_idstr(vars_with_idstr = {}) # # Adds the signals of the interface of the system. # self.each_signal do |sig| # vars_with_idstr[sig] = HDLRuby::High.vcd_idstr(sig) # end # Recurse on the signals. self.each_signal do |sig| sig.get_vars_with_idstr(vars_with_idstr) end # Recurse on the scope. return self.scope.get_vars_with_idstr(vars_with_idstr) end |
#init_sim(systemT) ⇒ Object
Initialize the simulation for system +systemT+.
236 237 238 239 240 241 242 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 236 def init_sim(systemT) # puts "init_sim for #{self} (#{self.name})" # Recurse on the signals. self.each_signal { |sig| sig.init_sim(systemT) } # Recure on the scope. self.scope.init_sim(systemT) end |
#init_untimeds ⇒ Object
Initialize the untimed objects.
245 246 247 248 249 250 251 252 253 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 245 def init_untimeds @untimeds.each do |obj| if obj.is_a?(Behavior) then obj.block.execute(:seq) else obj.execute(:seq) end end end |
#inout(*names) ⇒ Object
Declares high-level bit inout signals named +names+.
Retuns the last declared input.
819 820 821 |
# File 'lib/HDLRuby/hruby_high.rb', line 819 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.
805 806 807 |
# File 'lib/HDLRuby/hruby_high.rb', line 805 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+.
720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 |
# File 'lib/HDLRuby/hruby_high.rb', line 720 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.
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 |
# File 'lib/HDLRuby/hruby_high.rb', line 472 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.
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 |
# File 'lib/HDLRuby/hruby_high.rb', line 422 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.
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 |
# File 'lib/HDLRuby/hruby_high.rb', line 754 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.
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 |
# File 'lib/HDLRuby/hruby_high.rb', line 449 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. name.each do |key,value| res = self.add_output( SignalI.new(key,type,:output,value)) end else raise AnyError, "Invalid class for a name: #{name.class}" end end return res end |
#merge_included! ⇒ Object
Merge the included systems interface in current system. NOTE: incompatible with further to_low transformation.
844 845 846 847 848 849 850 |
# File 'lib/HDLRuby/hruby_high.rb', line 844 def merge_included! # puts "merge_included! for system=#{self.name}" # Recurse on the system instances. self.scope.merge_included! # Merge for current system. self.scope.merge_included(self) end |
#namespace ⇒ Object
Gets the private namespace of the system.
611 612 613 |
# File 'lib/HDLRuby/hruby_high.rb', line 611 def namespace return self.scope.namespace end |
#of?(system) ⇒ Boolean
Tell if the current system is a descedent of +system+
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 |
# File 'lib/HDLRuby/hruby_high.rb', line 388 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.
705 706 707 |
# File 'lib/HDLRuby/hruby_high.rb', line 705 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.
624 625 626 627 628 629 630 631 632 633 634 635 636 |
# File 'lib/HDLRuby/hruby_high.rb', line 624 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.
812 813 814 |
# File 'lib/HDLRuby/hruby_high.rb', line 812 def output(*names) self.make_outputs(bit,*names) end |
#remove_timed_behavior(beh) ⇒ Object
Remove timed beahvior +beh+
40 41 42 43 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 40 def remove_timed_behavior(beh) # puts "remove_timed_behavior" @timed_behaviors.delete(beh) end |
#run(&ruby_block) ⇒ Object
Execute +ruby_block+ in the context of the system.
616 617 618 |
# File 'lib/HDLRuby/hruby_high.rb', line 616 def run(&ruby_block) self.scope.open(&ruby_block) end |
#run_ack ⇒ Object
Acknowledge the run request the executable timed behavior.
287 288 289 290 291 292 293 294 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 287 def run_ack # puts "run_ack" mask = 0 @tim_exec.each { |beh| mask |= 2**beh.id } mask = 2**@total_timed_behaviors - 1 - mask @slave_flags_not &= mask @slave.broadcast end |
#run_done(id) ⇒ Object
Tell running part done for timed behavior +id+.
267 268 269 270 271 272 273 274 275 276 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 267 def run_done(id) # puts "run_done with id=#{id}" @num_done += 1 @slave_flags_not |= 2**id if @num_done == @tim_exec.size # puts "All done." @master_flag = 1 @master.signal end end |
#run_init(&ruby_block) ⇒ Object
Initialize run for executing +ruby_block+
256 257 258 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 256 def run_init(&ruby_block) @mutex.synchronize(&ruby_block) end |
#run_req(id) ⇒ Object
Request for running for timed behavior +id+
261 262 263 264 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 261 def run_req(id) # puts "run_req with id=#{id} and @slave_flags_not=#{@slave_flags_not}" @slave.wait(@mutex) while @slave_flags_not[id] == 1 end |
#run_wait ⇒ Object
Wait for all the run to complete.
279 280 281 282 283 284 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 279 def run_wait # puts "run_wait" @master.wait(@mutex) unless @master_flag == 1 @num_done = 0 @master_flag = 0 end |
#show_hierarchy(vcdout) ⇒ Object
Shows the hierarchy of the variables.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/HDLRuby/hruby_rsim_vcd.rb', line 121 def show_hierarchy(vcdout) # puts "show_hierarchy for module #{self} (#{self.name})" # Shows the current level of hierarchy. vcdout << "$scope module #{HDLRuby::High.vcd_name(self.name)} $end\n" # Shows the interface signals. self.each_signal do |sig| sig.show_hierarchy(vcdout) # # puts "showing signal #{HDLRuby::High.vcd_name(sig.fullname)}" # vcdout << "$var wire #{sig.type.width} " # vcdout << "#{HDLRuby::High.vcd_idstr(sig)} " # vcdout << "#{HDLRuby::High.vcd_name(sig.name)} $end\n" end # Recurse on the scope. self.scope.show_hierarchy(vcdout) # Close the current level of hierarchy. vcdout << "$upscope $end\n" end |
#show_init(vcdout) ⇒ Object
Initializes the displayer for generating a vcd on +vcdout+
297 298 299 300 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 297 def show_init(simout) # Sets the simulation output. @simout = simout end |
#show_signal(sig) ⇒ Object
Displays the value of signal +sig+.
308 309 310 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 308 def show_signal(sig) @simout.puts("#{sig.fullname}: #{sig.f_value.to_vstr}") end |
#show_string(str) ⇒ Object
Displays string +str+.
318 319 320 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 318 def show_string(str) @simout.print(str) end |
#show_time ⇒ Object
Displays the time.
303 304 305 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 303 def show_time @simout.puts("# #{@time}ps") end |
#show_value(val) ⇒ Object
Displays value +val+. NOTE: for now displays on the standard output and NOT the vcd.
313 314 315 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 313 def show_value(val) @simout.print(val.to_vstr) end |
#sim(simout) ⇒ Object
Run the simulation from the current systemT and outputs the resuts on simout.
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/HDLRuby/hruby_rsim.rb', line 112 def sim(simout) HDLRuby.show "Initializing Ruby-level simulator..." HDLRuby.show "#{Time.now}#{show_mem}" # Merge the included. self.merge_included! # Process par in seq. self.par_in_seq2seq! # Initializes the time. @time = 0 # Initializes the time and signals execution buffers. @tim_exec = [] @sig_exec = [] # Initilize the list of untimed objects. @untimeds = [] # Initialize the list of currently exisiting timed behavior. @timed_behaviors = [] # Initialize the list of activated signals. @sig_active = [] # Initializes the total number of timed behaviors (currently # existing or not: used for generating the id of the behaviors). @total_timed_behaviors = 0 # Initilizes the simulation. self.init_sim(self) # Initialize the displayer. self.show_init(simout) # Initialize the untimed objects. self.init_untimeds # puts "End of init_untimed." # Maybe there is nothing to execute. return if @total_timed_behaviors == 0 # Is there more than one timed behavior. if @total_timed_behaviors <= 1 then # No, no need of multithreading. @multithread = false # Simple execute the block of the behavior. @timed_behaviors[0].block.execute(:seq) else # Yes, need of multithreading. @multithread = true # Initializes the run mutex and the conditions. @mutex = Mutex.new @master = ConditionVariable.new @master_flag = 0 @slave = ConditionVariable.new @slave_flags_not = 0 @num_done = 0 # First all the timed behaviors are to be executed. @timed_behaviors.each {|beh| @tim_exec << beh } # But starts locked. @slave_flags_not = 2**@timed_behaviors.size - 1 # Starts the threads. @timed_behaviors.each {|beh| beh.make_thread } HDLRuby.show "Starting Ruby-level simulator..." HDLRuby.show "#{Time.now}#{show_mem}" # Run the simulation. self.run_init do # # Wake the behaviors. # @timed_behaviors.each {|beh| beh.run } until @tim_exec.empty? do # Execute the time behaviors that are ready. self.run_ack self.run_wait # Advance the global simulator. self.advance # # Display the time # self.show_time # shown_values = {} # # Get the behaviors waiting on activated signals. # until @sig_active.empty? do # # # Update the signals. # # @sig_active.each { |sig| sig.c_value = sig.f_value } # # puts "sig_active.size=#{@sig_active.size}" # # Look for the behavior sensitive to the signals. # @sig_active.each do |sig| # sig.each_anyedge { |beh| @sig_exec << beh } # if (sig.c_value.zero? && !sig.f_value.zero?) then # # puts "sig.c_value=#{sig.c_value.content}" # sig.each_posedge { |beh| @sig_exec << beh } # elsif (!sig.c_value.zero? && sig.f_value.zero?) then # sig.each_negedge { |beh| @sig_exec << beh } # end # end # # Update the signals. # @sig_active.each { |sig| sig.c_value = sig.f_value } # # puts "first @sig_exec.size=#{@sig_exec.size}" # @sig_exec.uniq! {|beh| beh.object_id } # # Display the activated signals. # @sig_active.each do |sig| # if !shown_values[sig].eql?(sig.f_value) then # self.show_signal(sig) # shown_values[sig] = sig.f_value # end # end # # Clear the list of active signals. # @sig_active.clear # # puts "sig_exec.size=#{@sig_exec.size}" # # Execute the relevant behaviors and connections. # @sig_exec.each { |obj| obj.execute(:par) } # @sig_exec.clear # @sig_active.uniq! {|sig| sig.object_id } # # puts "@sig_active.size=#{@sig_active.size}" # end # # Advance time. # @time = (@timed_behaviors.min {|b0,b1| b0.time <=> b1.time }).time break if @timed_behaviors.empty? # Schedule the next timed behavior to execute. @tim_exec = [] @timed_behaviors.each do |beh| @tim_exec << beh if beh.time == @time end # puts "@tim_exec.size=#{@tim_exec.size}" # puts "@timed_bevaviors.size=#{@timed_behaviors.size}" end end end end |
#singleton_instance ⇒ Object
Gets class containing the extension for the instances.
606 607 608 |
# File 'lib/HDLRuby/hruby_high.rb', line 606 def singleton_instance @singleton_instanceO.singleton_class end |
#to_low(name = self.name) ⇒ Object
Converts the system to HDLRuby::Low and set its +name+.
876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 |
# File 'lib/HDLRuby/hruby_high.rb', line 876 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(HDLRuby.uniq_name(name), # self.scope.to_low) systemTLN = HDLRuby.uniq_name(name) systemTL = HDLRuby::Low::SystemT.new(systemTLN, self.scope.to_low(systemTLN)) # 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_rcsim(rcowner = nil) ⇒ Object
Generate the C description of the systemT. +rcowner+ is the owner if any.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/HDLRuby/hruby_rcsim.rb', line 100 def to_rcsim(rcowner = nil) # puts "to_rcsim for systemT=#{self.name}(#{self})" # Create the systemT C object. @rcsystemT = RCSim.rcsim_make_systemT(self.name.to_s) # Sets the owner if any. if rcowner then RCSim.rcsim_set_owner(@rcsystemT,rcowner) end # Create and add the interface signals. if self.each_input.any? then RCSim.rcsim_add_systemT_inputs(@rcsystemT, self.each_input.map do |sig| sig.to_rcsim(@rcsystemT) end) end if self.each_output.any? then RCSim.rcsim_add_systemT_outputs(@rcsystemT, self.each_output.map do |sig| sig.to_rcsim(@rcsystemT) end) end if self.each_inout.any? then RCSim.rcsim_add_systemT_inouts(@rcsystemT, self.each_inout.map do |sig| sig.to_rcsim(@rcsystemT) end) end # Create and add the scope. RCSim.rcsim_set_systemT_scope(@rcsystemT, self.scope.to_rcsim(@rcsystemT)) # The owner is set afterward. # # Set the owner if any. # if @owner then # if @owner.is_a?(SystemI) then # puts "@owner=#{@owner} rcsystemI=#{@owner.rcsystemI.class}" # RCSim.rcsim_set_owner(@rcsystemT,@owner.rcsystemI) # end # # The non-SystemI owner are discarded for the simulation. # end return @rcsystemT end |
#to_ref ⇒ Object
Converts to a new reference.
415 416 417 |
# File 'lib/HDLRuby/hruby_high.rb', line 415 def to_ref return RefObject.new(this,self) end |
#to_user ⇒ Object
Converts to a namespace user.
409 410 411 412 |
# File 'lib/HDLRuby/hruby_high.rb', line 409 def to_user # Returns the scope. return @scope end |