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



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

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.



84
85
86
# File 'lib/HDLRuby/std/reconf.rb', line 84

def instance
  @instance
end

#nameObject (readonly)

The name of the reconfigurable component instance.



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

def name
  @name
end

#namespaceObject (readonly)

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



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

def namespace
  @namespace
end

Instance Method Details

#add_system(systemT) ⇒ Object

Adds system +systemT+.



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

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+



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

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.



268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/HDLRuby/std/reconf.rb', line 268

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.



254
255
256
257
258
259
# File 'lib/HDLRuby/std/reconf.rb', line 254

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.



234
235
236
237
238
239
# File 'lib/HDLRuby/std/reconf.rb', line 234

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.



244
245
246
247
248
249
# File 'lib/HDLRuby/std/reconf.rb', line 244

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.



285
286
287
# File 'lib/HDLRuby/std/reconf.rb', line 285

def index
    return @index
end

#set_main(systemT) ⇒ Object

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



222
223
224
225
226
227
228
229
# File 'lib/HDLRuby/std/reconf.rb', line 222

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.



292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/HDLRuby/std/reconf.rb', line 292

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



262
263
264
# File 'lib/HDLRuby/std/reconf.rb', line 262

def switcher(&ruby_block)
    @switcher_proc = ruby_block
end