Class: HDLRuby::High::Std::ReconfI

Inherits:
Object
  • Object
show all
Includes:
Hmissing
Defined in:
lib/HDLRuby/std/reconf.rb

Overview

Describes a high-level reconfigurable component instance.

Constant Summary

Constants included from Hmissing

Hmissing::High, Hmissing::NAMES

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Hmissing

#method_missing

Constructor Details

#initialize(name, &ruby_block) ⇒ ReconfI

Creates a new reconfigurable component instance with +name+ built from +ruby_block+.



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/HDLRuby/std/reconf.rb', line 85

def initialize(name,&ruby_block)
    # Check and set the name
    @name = name.to_sym

    # Sets the block for building:
    @ruby_block = ruby_block

    # Create the namespace for building the reconfigurable component.
    @namespace = Namespace.new(self)
    # # Make it give access to the internal of the class.
    # @namespace.add_method(:each_input, &method(:each_input))

    # Initialize the set of systems that can be used for this
    # component.
    @systemTs = []

    # Initialize the interface of the component.
    @inputs  = []
    @outputs = []
    @inouts  = []

    # Initialize the switch procedure to nil: it must be defined.
    @switcher_proc = nil
    # Initialize the reconfiguration index: it is defined when
    # building the reconfigurable object.
    @index = nil

    # Gives access to the reconfigurable component by registering
    # its name.
    obj = self
    HDLRuby::High.space_reg(@name) { obj }
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class HDLRuby::High::Hmissing

Instance Attribute Details

#instanceObject (readonly)

The instance representing the reconfigurable component.



81
82
83
# File 'lib/HDLRuby/std/reconf.rb', line 81

def instance
  @instance
end

#nameObject (readonly)

The name of the reconfigurable component instance.



74
75
76
# File 'lib/HDLRuby/std/reconf.rb', line 74

def name
  @name
end

#namespaceObject (readonly)

The namespace associated with the current execution when building a reconfigurable component, its reader or its writer.



78
79
80
# File 'lib/HDLRuby/std/reconf.rb', line 78

def namespace
  @namespace
end

Instance Method Details

#add_system(systemT) ⇒ Object

Adds system +systemT+.



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
# File 'lib/HDLRuby/std/reconf.rb', line 179

def add_system(systemT)
    # Checks the system.
    unless systemT.is_a?(SystemT) then
        raise "Invalid object for a systemT: #{systemT.class}"
    end
   
    # Expand the system to add to know the inputs.
    expanded = systemT.expand(:"")

    # Check its interface if it is not the firs system.
    unless @systemTs.empty? then
        expanded.each_input.with_index do |sig,idx|
            unless sig.eql?(@inputs[idx]) then
                raise "Invalid input signal ##{idx} for system " +
                    "#{systemT.name} got #{sig} but "+
                    "expecting: #{@inputs[idx]}"
            end
        end
        expanded.each_output.with_index do |sig,idx|
            unless sig.eql?(@outputs[idx]) then
                raise "Invalid output signal ##{idx} for system " +
                    "#{systemT.name} got #{sig} but "+
                    "expecting: #{@outputs[idx]}"
            end
        end
        expanded.each_inout.with_index do |sig,idx|
            unless sig.eql?(@inouts[idx]) then
                raise "Invalid inout signal ##{idx} for system " +
                    "#{systemT.name} got #{sig} but "+
                    "expecting: #{@inouts[idx]}"
            end
        end
    end

    # Add the system (not the expanded version!)
    @systemTs << systemT
    systemT
end

#build(*systemTs) ⇒ Object Also known as: call

Builds the reconfigurable component with systems types from +systems+



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
# File 'lib/HDLRuby/std/reconf.rb', line 120

def build(*systemTs)
    # Checks and sets the first system.
    if systemTs.empty? then
        raise "No system given for reconfiguble component: #{name}"
    end

    unless systemTs[0].is_a?(SystemT) then
        raise "Invalid object for a systemT: #{systems[0].class}"
    end
    # Set the default main systemT as the first one.
    @main = self.add_system(systemTs[0])

    # Sets the interface from the first system
    expanded = @main.expand(:"")
    expanded.each_input  {|sig| @inputs  << sig.clone }
    expanded.each_output {|sig| @outputs << sig.clone }
    expanded.each_inout  {|sig| @inouts  << sig.clone }

    # Add the other systems.
    systemTs[1..-1].each { |systemT| self.add_system(systemT) }

    # Generate the name and the size of the reconfiguration index
    # signal.
    index_name = HDLRuby.uniq_name
    index_size = systemTs.size.width
    index_ref  = nil # The reference to the signal, will be set
                     # in the context of the current system.

    # Builds the reconfigurable component.
    ruby_block = @ruby_block
    HDLRuby::High.space_push(@namespace)
    HDLRuby::High.top_user.instance_eval do
        # Generate the index
        index_ref = [index_size].inner(index_name)
    end
    HDLRuby::High.top_user.instance_eval(&ruby_block)
    HDLRuby::High.space_pop
    
    # Set the index signal.
    @index = index_ref

    # Builds the system instance.
    # Creates its name.
    name = HDLRuby.uniq_name
    # Make the instantiation of the main system.
    @instance = @main.instantiate(name)
    # Adds the other possible systems.
    @systemTs.each do |systemT|
        unless systemT == @main
            systemT = systemT.expand(systemT.name.to_s + ":rT")
            @instance.add_systemT(systemT)
        end
    end
end

#command(name, &ruby_block) ⇒ Object

Defines new command +name+ to execute +ruby_block+ for the channel.



265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/HDLRuby/std/reconf.rb', line 265

def command(name,&ruby_block)
    # Ensures name is a symbol.
    name = name.to_sym
    # Sets the new command.
    self.define_singleton_method(name) do
        # Executes the command in the right environment.
        HDLRuby::High.space_push(@namespace)
        res = HDLRuby::High.top_user.instance_exec(&ruby_block)
        HDLRuby::High.space_pop
        res
    end
end

#each_inout(&ruby_block) ⇒ Object

Iterates on the inout signals.

Returns an enumerator if no ruby block is given.



251
252
253
254
255
256
# File 'lib/HDLRuby/std/reconf.rb', line 251

def each_inout(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_inout) unless ruby_block
    # A ruby block? Apply it on each inout signal instance.
    @inouts.each(&ruby_block)
end

#each_input(&ruby_block) ⇒ Object

Iterates on the input signals.

Returns an enumerator if no ruby block is given.



231
232
233
234
235
236
# File 'lib/HDLRuby/std/reconf.rb', line 231

def each_input(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_input) unless ruby_block
    # A ruby block? Apply it on each input signal instance.
    @inputs.each(&ruby_block)
end

#each_output(&ruby_block) ⇒ Object

Iterates on the output signals.

Returns an enumerator if no ruby block is given.



241
242
243
244
245
246
# File 'lib/HDLRuby/std/reconf.rb', line 241

def each_output(&ruby_block)
    # No ruby block? Return an enumerator.
    return to_enum(:each_output) unless ruby_block
    # A ruby block? Apply it on each output signal instance.
    @outputs.each(&ruby_block)
end

#indexObject

Gives access to the signal giving the current reconfiguration index.



282
283
284
# File 'lib/HDLRuby/std/reconf.rb', line 282

def index
    return @index
end

#set_main(systemT) ⇒ Object

Sets and adds a new main system to be +systemT+.



219
220
221
222
223
224
225
226
# File 'lib/HDLRuby/std/reconf.rb', line 219

def set_main(systemT)
    # puts "set_main with systemT=#{systemT.name}"
    # Add the system if not already present.
    # NOTE: also checks the system.
    systemT = self.add_system(systemT)
    # Set the system to be a main.
    @main = systemT
end

#switch(idx, &ruby_block) ⇒ Object

Generate the switching code to configuration number +idx+, and executing the code generated by +ruby_block+ when the switch is completed.



289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/HDLRuby/std/reconf.rb', line 289

def switch(idx,&ruby_block)
    switcher_proc = @switcher_proc
    index = @index
    inputs = @inputs
    outputs = @outputs
    inouts = @inouts
    systemTs = @systemTs
    # Execute the code generating the reader in context.
    HDLRuby::High.space_push(@namespace)
    HDLRuby::High.cur_block.open do
        instance_exec(idx,ruby_block,&switcher_proc)
    end
    HDLRuby::High.space_pop
end

#switcher(&ruby_block) ⇒ Object

Defines the switching command to be +ruby_block+.



259
260
261
# File 'lib/HDLRuby/std/reconf.rb', line 259

def switcher(&ruby_block)
    @switcher_proc = ruby_block
end