Class: HDLRuby::High::SystemI

Inherits:
Low::SystemI show all
Includes:
SingletonExtend, WithFullname
Defined in:
lib/HDLRuby/hruby_high.rb,
lib/HDLRuby/hruby_rsim.rb,
lib/HDLRuby/hruby_rcsim.rb,
lib/HDLRuby/hruby_high_fullname.rb

Overview

Describes a system instance.

NOTE: an instance can actually represented muliple layers of systems, the first one being the one actually instantiated in the final RTL code. This layering can be used for describing software or partial (re)configuration.

Constant Summary collapse

High =
HDLRuby::High

Constants included from Low::Low2Symbol

Low::Low2Symbol::Low2SymbolPrefix, Low::Low2Symbol::Low2SymbolTable, Low::Low2Symbol::Symbol2LowTable

Instance Attribute Summary collapse

Attributes inherited from Low::SystemI

#name, #systemT

Attributes included from Low::Hparent

#parent

Instance Method Summary collapse

Methods included from WithFullname

#fullname

Methods included from SingletonExtend

#eigen_extend

Methods inherited from Low::SystemI

#add_systemT, #each_arrow_deep, #each_behavior, #each_behavior_deep, #each_block_deep, #each_connection, #each_connection_deep, #each_deep, #each_inner, #each_inout, #each_input, #each_output, #each_sensitive_deep, #each_signal, #each_signal_deep, #each_statement_deep, #each_systemI, #each_systemT, #eql?, #get_by_name, #get_inner, #get_inout, #get_input, #get_output, #get_signal, #get_signal_splits, #get_systemI, #hash, #replace_names!, #set_name!, #set_systemT, #to_c, #to_ch, #to_hdr, #to_high, #to_vhdl, #with_port!, #with_var!

Methods included from Low::Low2Symbol

#to_sym

Methods included from Low::Hparent

#absolute_ref, #hierarchy, #no_parent!, #scope

Constructor Details

#initialize(name, systemT) ⇒ SystemI

Creates a new system instance of system type systemT named name.



2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
# File 'lib/HDLRuby/hruby_high.rb', line 2512

def initialize(name, systemT)
    # Check the validity of the name.
    unless name.is_a?(String) or name.is_a?(Symbol)
        raise AnyError, 
          "Missing instance name for system instantiation."
    end
    # Initialize the system instance structure.
    super(name,systemT)

    # Sets the hdl-like access to the system instance.
    obj = self # For using the right self within the proc
    High.space_reg(name) { obj }
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &ruby_block) ⇒ Object

Missing methods are looked for in the public namespace of the system type.



2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
# File 'lib/HDLRuby/hruby_high.rb', line 2677

def method_missing(m, *args, &ruby_block)
    # print "method_missing in class=#{self.class} with m=#{m}\n"
    # Maybe its a signal reference.
    signal = self.systemT.get_signal_with_included(m)
    if signal then
        # Yes, create the reference.
        return RefObject.new(self.to_ref,signal)
    else
        # No try elsewhere
        self.public_namespace.send(m,*args,&ruby_block)
    end
end

Instance Attribute Details

#rcsystemIObject (readonly)

Extends the SystemI class for hybrid Ruby-C simulation.



483
484
485
# File 'lib/HDLRuby/hruby_rcsim.rb', line 483

def rcsystemI
  @rcsystemI
end

Instance Method Details

#call(*connects) ⇒ Object

Connects signals of the system instance according to connects.

NOTE: connects can be a hash table where each entry gives the correspondance between a system's signal name and an external signal to connect to, or a list of signals that will be connected in the order of declaration.



2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
# File 'lib/HDLRuby/hruby_high.rb', line 2548

def call(*connects)
    # Checks if it is a connection through is a hash.
    if connects.size == 1 and connects[0].respond_to?(:to_h) and
        !connects[0].is_a?(HRef) then
        # Yes, perform a connection by name
        connects = connects[0].to_h
        # Performs the connections.
        connects.each do |key,value|
            # Gets the signal corresponding to connect.
            signal = self.systemT.get_signal_with_included(key)
            unless signal then
              raise AnyError, "Invalid parameter: #{key}"
            end
            # Check if it is an output.
            isout = self.systemT.get_output_with_included(key)
            # Convert it to a reference.
            # puts "key=#{key} value=#{value} signal=#{signal}"
            ref = RefObject.new(self.to_ref,signal)
            # Make the connection.
            if isout then
                value <= ref
            else
                ref <= value
            end
        end
    else
        # No, perform a connection is order of declaration
        # But first check if there are not too many of them.
      if connects.size > 
        self.systemT.each_signal_with_included.to_a.size then
            raise AnyError, "Too many connections to instance " +
              "#{self.name}: got #{connects.size} " +
              "but expecting at most " +
              "#{self.systemT.each_signal_with_included.to_a.size}"
        end
        connects.each.with_index do |csig,i|
        # Now do the connection.
            # puts "systemT inputs=#{systemT.each_input.to_a.size}"
            # Gets i-est signal to connect
            ssig = self.systemT.get_interface_with_included(i)
            # Check if it is an output.
            isout = self.systemT.get_output_with_included(ssig.name)
            # puts "ssig=#{ssig.name} isout=#{isout}"
            # Convert it to a reference.
            ssig = RefObject.new(self.to_ref,ssig)
            # Make the connection.
            if isout then
                csig <= ssig
                # csig.to_ref <= ssig
            else
                ssig <= csig
                # ssig <= csig.to_expr
            end
        end
    end
end

#choice(configuration = {}) ⇒ Object

Adds alternative system systemT



2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
# File 'lib/HDLRuby/hruby_high.rb', line 2626

def choice(configuration = {})
    # Process the argument.
    configuration.each do |k,v|
        k = k.to_sym
        unless v.is_a?(SystemT) then
            raise "Invalid class for a system type: #{v.class}"
        end
        # Create an eigen system.
        eigen = v.instantiate(HDLRuby.uniq_name(self.name)).systemT
        # Ensure its interface corresponds.
        my_signals = self.each_signal.to_a
        if (eigen.each_signal.with_index.find { |sig,i|
            !sig.eql?(my_signals[i])
        }) then
        raise "Invalid system for configuration: #{systemT.name}." 
        end
        # Add it.
        # At the HDLRuby::High level
        @choices = { self.name => self.systemT } unless @choices
        @choices[k] = eigen
        # At the HDLRuby::Low level
        self.add_systemT(eigen)
    end
end

#configure(sys) ⇒ Object

(Re)Configuration of system instance to systemT designated by sys. sys may be the index or the name of the configuration, the first configuration being named by the systemI name.



2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
# File 'lib/HDLRuby/hruby_high.rb', line 2654

def configure(sys)
    if sys.respond_to?(:to_i) then
        # The argument is an index.
        # Create the (re)configuration node.
        High.top_user.add_statement(
            Configure.new(RefObject.new(RefThis.new,self),sys.to_i))
    else
        # The argument is a name (should be).
        # Get the index corresponding to the name.
        num = @choices.find_index { |k,_| k == sys.to_sym }
        unless num then
            raise "Invalid name for configuration: #{sys.to_s}"
        end
        # Create the (re)configuration node.
        High.top_user.add_statement(
            Configure.new(RefObject.new(RefThis.new,self),num))
    end
end

#get_export(name) ⇒ Object

Gets an exported element (signal or system instance) by name.



2606
2607
2608
# File 'lib/HDLRuby/hruby_high.rb', line 2606

def get_export(name)
    return @systemT.get_export(name)
end

#init_sim(systemT) ⇒ Object

Initialize the simulation for system systemT.



670
671
672
673
# File 'lib/HDLRuby/hruby_rsim.rb', line 670

def init_sim(systemT)
    # Recurse on the Eigen system.
    self.systemT.init_sim(systemT)
end

#namespaceObject

Gets the private namespace.



2699
2700
2701
# File 'lib/HDLRuby/hruby_high.rb', line 2699

def namespace
    self.systemT.namespace
end

#open(&ruby_block) ⇒ Object

Opens for extension.

NOTE: actually executes ruby_block in the context of the systemT.



2615
2616
2617
2618
2619
2620
2621
2622
2623
# File 'lib/HDLRuby/hruby_high.rb', line 2615

def open(&ruby_block)
    # Ensure there is a block.
    ruby_block = proc {} unless block_given?
    # Extend the eigen system.
    @systemT.run(&ruby_block)
    # Update the methods.
    @systemT.eigenize(self)
    self.eigen_extend(@systemT.public_namespace)
end

#public_namespaceObject

Gets the public namespace.



2694
2695
2696
# File 'lib/HDLRuby/hruby_high.rb', line 2694

def public_namespace
    self.systemT.public_namespace
end

#to_low(name = self.name) ⇒ Object

Converts the instance to HDLRuby::Low and set its name.



2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
# File 'lib/HDLRuby/hruby_high.rb', line 2705

def to_low(name = self.name)
    # puts "to_low with #{self} (#{self.name}) #{self.systemT}"
    # Converts the system of the instance to HDLRuby::Low
    systemTL = self.systemT.to_low
    # Creates the resulting HDLRuby::Low instance
    systemIL = HDLRuby::Low::SystemI.new(High.names_create(name),
                                     systemTL)
    # # For debugging: set the source high object 
    # systemIL.properties[:low2high] = self.hdr_id
    # self.properties[:high2low] = systemIL
    # Adds the other systemTs.
    self.each_systemT do |systemTc|
        if systemTc != self.systemT
            systemTcL = systemTc.to_low
            systemIL.add_systemT(systemTcL)
        end
    end
    return systemIL
end

#to_rcsim(rcowner) ⇒ Object

Generate the C description of the signal comming from object whose C description is rcowner



487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
# File 'lib/HDLRuby/hruby_rcsim.rb', line 487

def to_rcsim(rcowner)
    # puts "to_rcsim for systemI=#{self.name}(#{self})"
    # Create the system instance C object.
    @rcsystemI = RCSim.rcsim_make_systemI(self.name.to_s,
                                          self.systemT.to_rcsim)
    # # Set the owner of the systemT.
    # RCSim.rcsim_set_owner(self.systemT.rcsystemT,@rcsystemI)
    # Set the owner of the systemT as the same as the systemI since
    # it is an Eigen system.
    RCSim.rcsim_set_owner(self.systemT.rcsystemT,rcowner)

    # Set the owner.
    RCSim.rcsim_set_owner(@rcsystemI,rcowner)

    # Add the alternate system types.
    if self.each_systemI.any? then
        RCSim.rcsim_add_systemI_systemTs(@rcsystemI,
                                         self.each_systemT.select do|sys|
            sys != self.systemT
        end.map do |sys|
            # sys.to_rcsim(@rcsystemI)
            sys.to_rcsim(rcowner)
        end)
    end

    return @rcsystemI
end

#to_refObject

Converts to a new reference.



2532
2533
2534
2535
2536
2537
2538
2539
2540
# File 'lib/HDLRuby/hruby_high.rb', line 2532

def to_ref
    if self.name.empty? then
        # No name, happens if inside the systemI so use this.
        return this
    else
        # A name.
        return RefObject.new(this,self)
    end
end

#typeObject

The type of a systemI: for now Void (may change in the future).



2527
2528
2529
# File 'lib/HDLRuby/hruby_high.rb', line 2527

def type
    return void
end