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

Extends the SystemI class for hybrid Ruby-C simulation.

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_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

#hierarchy, #no_parent!, #scope

Constructor Details

#initialize(name, systemT) ⇒ SystemI

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



2203
2204
2205
2206
2207
2208
2209
2210
# File 'lib/HDLRuby/hruby_high.rb', line 2203

def initialize(name, systemT)
    # 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.



2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
# File 'lib/HDLRuby/hruby_high.rb', line 2367

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)

Returns the value of attribute rcsystemI.



457
458
459
# File 'lib/HDLRuby/hruby_rcsim.rb', line 457

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.



2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
# File 'lib/HDLRuby/hruby_high.rb', line 2234

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.get_signal(key)
            # unless signal then
            #     # Look into the included systems.
            #     self.systemT.scope.each_included do |included|
            #         signal = included.get_signal(key)
            #         break if signal
            #     end
            # end
            signal = self.systemT.get_signal_with_included(key)
            # Check if it is an output.
            # isout = self.get_output(key)
            # unless isout then
            #     # Look into the inlucded systems.
            #     self.systemT.scope.each_included do |included|
            #         isout = included.get_output(key)
            #         break if isout
            #     end
            # end
            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
        connects.each.with_index do |csig,i|
            # 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+



2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
# File 'lib/HDLRuby/hruby_high.rb', line 2316

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.



2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
# File 'lib/HDLRuby/hruby_high.rb', line 2344

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+.



2296
2297
2298
# File 'lib/HDLRuby/hruby_high.rb', line 2296

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

#init_sim(systemT) ⇒ Object

Initialize the simulation for system +systemT+.



569
570
571
572
# File 'lib/HDLRuby/hruby_rsim.rb', line 569

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

#namespaceObject

Gets the private namespace.



2389
2390
2391
2392
# File 'lib/HDLRuby/hruby_high.rb', line 2389

def namespace
    # self.systemT.scope.namespace
    self.systemT.namespace
end

#open(&ruby_block) ⇒ Object

Opens for extension.

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



2305
2306
2307
2308
2309
2310
2311
2312
2313
# File 'lib/HDLRuby/hruby_high.rb', line 2305

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.



2384
2385
2386
# File 'lib/HDLRuby/hruby_high.rb', line 2384

def public_namespace
    self.systemT.public_namespace
end

#to_low(name = self.name) ⇒ Object

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



2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
# File 'lib/HDLRuby/hruby_high.rb', line 2396

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+



461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
# File 'lib/HDLRuby/hruby_rcsim.rb', line 461

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.
    # self.each_systemT do |systemT|
    #     rcsys = systemT.to_rcsim(@rcsystemI)
    #     RCSim.rcsim_add_systemI_systemT(@rcsystemI,rcsys)
    # end
    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.



2218
2219
2220
2221
2222
2223
2224
2225
2226
# File 'lib/HDLRuby/hruby_high.rb', line 2218

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).



2213
2214
2215
# File 'lib/HDLRuby/hruby_high.rb', line 2213

def type
    return void
end