HDLRuby 3.0.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/HDLRuby.gemspec +1 -0
  3. data/README.md +149 -79
  4. data/ext/hruby_sim/hruby_rcsim_build.c +2 -0
  5. data/ext/hruby_sim/hruby_sim_calc.c +33 -6
  6. data/ext/hruby_sim/hruby_sim_tree_calc.c +111 -22
  7. data/lib/HDLRuby/hdr_samples/comparison_bench.rb +2 -2
  8. data/lib/HDLRuby/hdr_samples/constant_in_function.rb +2 -1
  9. data/lib/HDLRuby/hdr_samples/counter_bench.rb +1 -1
  10. data/lib/HDLRuby/hdr_samples/counter_dff_bench.rb +8 -7
  11. data/lib/HDLRuby/hdr_samples/dff_properties.rb +2 -0
  12. data/lib/HDLRuby/hdr_samples/enum_as_param.rb +52 -0
  13. data/lib/HDLRuby/hdr_samples/linear_test.rb +2 -0
  14. data/lib/HDLRuby/hdr_samples/logic_bench.rb +6 -0
  15. data/lib/HDLRuby/hdr_samples/mei8.rb +6 -6
  16. data/lib/HDLRuby/hdr_samples/mei8_bench.rb +6 -6
  17. data/lib/HDLRuby/hdr_samples/memory_test.rb +2 -0
  18. data/lib/HDLRuby/hdr_samples/named_sub.rb +9 -5
  19. data/lib/HDLRuby/hdr_samples/ram.rb +7 -6
  20. data/lib/HDLRuby/hdr_samples/ruby_fir_hw.rb +2 -0
  21. data/lib/HDLRuby/hdr_samples/struct.rb +15 -3
  22. data/lib/HDLRuby/hdr_samples/with_bram.rb +1 -1
  23. data/lib/HDLRuby/hdr_samples/with_bram_frame_stack.rb +1 -1
  24. data/lib/HDLRuby/hdr_samples/with_bram_stack.rb +1 -1
  25. data/lib/HDLRuby/hdr_samples/with_channel.rb +2 -0
  26. data/lib/HDLRuby/hdr_samples/with_channel_other.rb +2 -0
  27. data/lib/HDLRuby/hdr_samples/with_class.rb +3 -1
  28. data/lib/HDLRuby/hdr_samples/with_connector.rb +2 -0
  29. data/lib/HDLRuby/hdr_samples/with_connector_memory.rb +2 -0
  30. data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +6 -0
  31. data/lib/HDLRuby/hdr_samples/with_fixpoint_adv.rb +73 -0
  32. data/lib/HDLRuby/hdr_samples/with_leftright.rb +1 -1
  33. data/lib/HDLRuby/hdr_samples/with_ref_expr.rb +30 -0
  34. data/lib/HDLRuby/hdr_samples/with_sequencer.rb +49 -37
  35. data/lib/HDLRuby/hdr_samples/with_sequencer_channel.rb +58 -0
  36. data/lib/HDLRuby/hdr_samples/with_sequencer_enumerable.rb +113 -69
  37. data/lib/HDLRuby/hdr_samples/with_sequencer_enumerator.rb +28 -14
  38. data/lib/HDLRuby/hdr_samples/with_sequencer_func.rb +63 -0
  39. data/lib/HDLRuby/hdr_samples/with_sequencer_sync.rb +2 -1
  40. data/lib/HDLRuby/hdrcc.rb +13 -1
  41. data/lib/HDLRuby/hruby_high.rb +105 -31
  42. data/lib/HDLRuby/hruby_low.rb +127 -3
  43. data/lib/HDLRuby/hruby_low2programs.rb +47 -0
  44. data/lib/HDLRuby/hruby_low_resolve.rb +3 -2
  45. data/lib/HDLRuby/hruby_low_without_namespace.rb +133 -5
  46. data/lib/HDLRuby/hruby_low_without_subsignals.rb +51 -12
  47. data/lib/HDLRuby/hruby_rcsim.rb +24 -1
  48. data/lib/HDLRuby/hruby_serializer.rb +2 -1
  49. data/lib/HDLRuby/hruby_types.rb +5 -5
  50. data/lib/HDLRuby/hruby_values.rb +7 -7
  51. data/lib/HDLRuby/hruby_verilog.rb +193 -35
  52. data/lib/HDLRuby/hruby_verilog_name.rb +35 -42
  53. data/lib/HDLRuby/std/fixpoint.rb +2 -2
  54. data/lib/HDLRuby/std/fsm.rb +10 -1
  55. data/lib/HDLRuby/std/function_generator.rb +1 -1
  56. data/lib/HDLRuby/std/linear.rb +7 -7
  57. data/lib/HDLRuby/std/sequencer.rb +538 -60
  58. data/lib/HDLRuby/std/sequencer_channel.rb +90 -0
  59. data/lib/HDLRuby/std/sequencer_func.rb +546 -0
  60. data/lib/HDLRuby/std/std.rb +2 -0
  61. data/lib/HDLRuby/version.rb +1 -1
  62. data/tuto/tutorial_sw.md +267 -61
  63. metadata +25 -4
  64. data/lib/HDLRuby/hdr_samples/with_register_stack.rb +0 -150
@@ -0,0 +1,90 @@
1
+ require 'std/sequencer'
2
+
3
+ module HDLRuby::High::Std
4
+
5
+ ##
6
+ # Standard HDLRuby::High library: channel generator.
7
+ # The idea is to have abstract communication interface whose
8
+ # implementation can be seamlessly modified.
9
+ #
10
+ ########################################################################
11
+
12
+
13
+
14
+
15
+
16
+ # Creates an abstract channel over an accessing method.
17
+ # NOTE: Works like an enumerator, but can be passed as generic arguments and
18
+ # generates a different enumerator per sequencer.
19
+ # - +typ+ is the data type of the elements.
20
+ # - +size+ is the number of elements.
21
+ # - +access+ is the block implementing the access method.
22
+ class SequencerChannel < SEnumerator
23
+
24
+ # Create a new channel for +size+ elements of type +type+ with an JW
25
+ # array-like accesser +access+.
26
+ def initialize(typ,size,&access)
27
+ @type = typ
28
+ @size = size
29
+ @access = access
30
+ @enums = {} # The enumerator per sequencer.
31
+ end
32
+
33
+ # Get the enumerator for current sequencer.
34
+ # If does not exist create a new one.
35
+ def senumerator
36
+ unless SequencerT.current then
37
+ raise "Cannot get a channel enumerator from outside a sequencer."
38
+ end
39
+ enum = @enums[SequencerT.current]
40
+ unless enum then
41
+ enum = @enums[SequencerT.current] =
42
+ SEnumeratorBase.new(@type,@size,&@access)
43
+ end
44
+ return enum
45
+ end
46
+
47
+ # Clones is ambigous here, so deactivated.
48
+ def clone
49
+ raise "clone not supported for channels."
50
+ end
51
+
52
+ # The array read accesses.
53
+ def [](addr)
54
+ return @access.call(addr)
55
+ end
56
+
57
+ # The array write access.
58
+ def []=(addr,val)
59
+ return @access.call(addr,val)
60
+ end
61
+
62
+ # The access to the already defined elements.
63
+ attr_reader :type
64
+ attr_reader :size
65
+
66
+ # Delegate the enumeration methods to the enumerator of the current
67
+ # system.
68
+
69
+ [:result,:index,:access,:speek,
70
+ :snext,:snext?,:snext!,:srewind].each do |sym|
71
+ define_method(sym) do |*args,&ruby_block|
72
+ senumerator.send(sym,*args,&ruby_block)
73
+ end
74
+ end
75
+ end
76
+
77
+
78
+
79
+ # Creates an abstract channel over an accessing method.
80
+ # NOTE: Works like an enumerator or a memory access, but can be passed as
81
+ # generic arguments and generates a different enumerator per sequencer
82
+ # (memory access is identical for now though).
83
+ # - +typ+ is the data type of the elements.
84
+ # - +size+ is the number of elements.
85
+ # - +access+ is the block implementing the access method.
86
+ def schannel(typ,size,&access)
87
+ return SequencerChannel.new(typ,size,&access)
88
+ end
89
+
90
+ end
@@ -0,0 +1,546 @@
1
+ require 'std/sequencer'
2
+
3
+ module HDLRuby::High::Std
4
+
5
+ ##
6
+ # Standard HDLRuby::High library: sequencer function generator.
7
+ # The idea is to be able to write sw-like sequential code.
8
+ #
9
+ ########################################################################
10
+
11
+
12
+
13
+ # Describes a sequencer function definition.
14
+ #
15
+ # NOTE: like with ruby, functions does not have types for their arguments,
16
+ # their are set when the function is called.
17
+ # This is handle by the eigen functions (see SequencerFunctionE).
18
+ class SequencerFunctionT
19
+
20
+ ZERO = :_b0.to_value
21
+ ONE = :_sb01.to_value
22
+ # ZERO = 0
23
+ # ONE = 1
24
+
25
+ # The name of the function.
26
+ attr_reader :name
27
+
28
+ # The body of the function.
29
+ attr_reader :body
30
+
31
+ # The stack overflow code of the function if any.
32
+ attr_reader :overflow
33
+
34
+ # Creates a new sequencer function named +name+, with stack size +depth+
35
+ # executing code given by +ruby_block+. Additionaly a HDLRuby block
36
+ # +overflow+ can be added to be executed when a stack overflow occured.
37
+ #
38
+ # NOTE: if +depth+ is nil it will be automatically computed at call time.
39
+ def initialize(name, depth = nil, overflow = nil, &ruby_block)
40
+ @name = name.to_sym
41
+ @body = ruby_block
42
+ @depth = depth ? depth.to_i : nil
43
+ @overflow = overflow ? overflow.to_proc : nil
44
+ end
45
+
46
+ # Call the function with arguments +args+.
47
+ def call(*args)
48
+ # Check if there are extra arguments, they are used for configuring
49
+ # the stack.
50
+ if args.size > @body.arity then
51
+ # The first extra argument is the depth of the stack for this
52
+ # specific call.
53
+ @depth = args.delete_at(@body.arity)
54
+ end
55
+
56
+ # Specialize the function with the types of the arguments.
57
+ # (the result is the eigen function of funcI).
58
+ funcE = SequencerFunctionE.new(self, args.map {|arg| arg.type })
59
+ # Check if it is a recursion.
60
+ funcI = SequencerFunctionI.recursion(funcE)
61
+ if funcI then
62
+ # puts "Recursive call"
63
+ # Recursion, set the size of the stack.
64
+ funcI.make_depth(@depth)
65
+ # Call the function.
66
+ st_call = funcI.recurse_call(*args)
67
+ # adds the return address.
68
+ depth = funcI.depth
69
+ stack_ptr = funcI.stack_ptr
70
+ # st_call.gotos << proc do
71
+ old_code = st_call.code
72
+ st_call.code = proc do
73
+ old_code.call
74
+ HDLRuby::High.top_user.instance_exec do
75
+ # hprint("returning with stack_ptr=",stack_ptr,"\n")
76
+ hif(stack_ptr <= depth) do
77
+ # hprint("poking recursive return value at idx=",funcI.returnIdx," with value=",st_call.value+1,"\n")
78
+ funcI.poke(funcI.returnIdx,st_call.value + ONE)
79
+ end
80
+ end
81
+ end
82
+ else
83
+ # puts "First call"
84
+ # No recursion, create an instance of the function
85
+ funcI = SequencerFunctionI.new(funcE)
86
+ # Call the function.
87
+ st_call = funcI.first_call(*args)
88
+ # Build the function... Indeed after the call, that
89
+ # allows to avoid one state.
90
+ st_func = funcI.build
91
+ # adds the return value.
92
+ # st_call.gotos << proc do
93
+ old_code = st_call.code
94
+ st_call.code = proc do
95
+ old_code.call
96
+ HDLRuby::High.top_user.instance_exec do
97
+ # hprint("poking return value at idx=",funcI.returnIdx," with value=",st_func.value+1,"\n")
98
+ funcI.poke(funcI.returnIdx,st_func.value + ONE)
99
+ end
100
+ end
101
+ end
102
+ # Return the created funcI return value.
103
+ return funcI.return_value
104
+ end
105
+ end
106
+
107
+ # Describes a sequencer eigen function.
108
+ # Here, an eigen function is a function definition specilized with
109
+ # arguments types.
110
+ class SequencerFunctionE
111
+
112
+ attr_reader :funcT
113
+
114
+ ## Creates a new eigen function with function type +funcT+ and arguments
115
+ # types +argTs+.
116
+ def initialize(funcT, argTs)
117
+ @funcT = funcT
118
+ @argTs = argTs.to_a
119
+ end
120
+
121
+ ## Gets the name of the function.
122
+ def name
123
+ @funcT.name
124
+ end
125
+
126
+ ## Gets the body of the function.
127
+ def body
128
+ @funcT.body
129
+ end
130
+
131
+ ## Gets the stack overflow code of the function.
132
+ def overflow
133
+ @funcT.overflow
134
+ end
135
+
136
+ # Iterates over the argument types.
137
+ #
138
+ # Returns an enumerator if no ruby block is given.
139
+ def each_argT(&ruby_block)
140
+ # No ruby block? Return an enumerator.
141
+ return to_enum(:each_argT) unless ruby_block
142
+ # A ruby block? Apply it on each agument type.
143
+ @argTs.each(&ruby_block)
144
+ end
145
+
146
+ # Comparison of eigen functions.
147
+ def ==(obj)
148
+ # Is obj an eigen function?
149
+ return false unless obj.is_a?(SequencerFunctionE)
150
+ # Has obj the same function type?
151
+ return false unless self.funcT == obj.funcT
152
+ # Has obj the same argument types?
153
+ return obj.each_argT.zip(self.each_argT).all? {|t0,t1| t0 == t1 }
154
+ end
155
+ end
156
+
157
+
158
+ # Describes a sequencer function instance.
159
+ class SequencerFunctionI
160
+
161
+ ZERO = SequencerFunctionT::ZERO
162
+ ONE = SequencerFunctionT::ONE
163
+
164
+
165
+ @@current_stack = [] # The stack of current function instance.
166
+
167
+ # Get the function instance currently processing.
168
+ def self.current
169
+ @@current_stack[-1]
170
+ end
171
+
172
+ # The eigen function.
173
+ attr_reader :funcE
174
+
175
+ # The return index in the stacks.
176
+ attr_reader :returnIdx
177
+
178
+ # The stack pointer register.
179
+ attr_reader :stack_ptr
180
+
181
+ # The depth of the stack.
182
+ attr_reader :depth
183
+
184
+ # Creates a new instance of function from +funcE+ eigen function,
185
+ # and possible default stack depth +depth+.
186
+ def initialize(funcE)
187
+ # Sets the eigen function.
188
+ @funcE = funcE
189
+ # Initialize the depth.
190
+ # At first, no recursion is assumed, hence the depth is 1.
191
+ @depth = 1
192
+ # Create the table of signal stacks (by name).
193
+ # For further updating.
194
+ @stack_sigs = [] # Signal stacks
195
+ # Signal stacks pointer.
196
+ stack_ptr = nil
197
+ depth = @depth
198
+ HDLRuby::High.cur_system.open do
199
+ stack_ptr = bit[depth.width].inner(HDLRuby.uniq_name(:stack_ptr) => 0)
200
+ end
201
+ @stack_ptr = stack_ptr
202
+ # Create the stack for the returns.
203
+ # @returnIdx = self.make_stack(bit[SequencerT.current.size.width])
204
+ @returnIdx = self.make_stack(bit[8])
205
+ # Create the stacks for the arguments.
206
+ @funcE.each_argT { |argT| self.make_stack(argT) }
207
+ # @argsIdx = @returnIdx + 2
208
+ @argsIdx = @returnIdx + ONE
209
+
210
+ # Create the return value, however, at first their type is unknown
211
+ # to set it as a simple bit.
212
+ # The type of the return value is built when calling make_return.
213
+ # @returnValIdx = self.make_stack(bit[1])
214
+ # puts "@returnValIdx=#{@returnValIdx}"
215
+ returnValue = nil
216
+ name = @funcE.name
217
+ HDLRuby::High.cur_system.open do
218
+ returnValue = bit[1].inner(
219
+ HDLRuby.uniq_name("#{name}_return"))
220
+ end
221
+ @returnValue = returnValue
222
+
223
+ # Initialize the state where the initial function call will be.
224
+ @state = nil
225
+ end
226
+
227
+ ## Give access to the return value.
228
+ #
229
+ # NOTE: is automatically called when within an expression.
230
+ def to_expr
231
+ return self.return_value
232
+ end
233
+
234
+ # There is actually recurse, compute the depth: if +depth+ is given
235
+ # as argument, this is the depth, otherwise compute it from the
236
+ # bit width of the argument.
237
+ #
238
+ # NOTE: uses the heuristic that the depth is more or less equal to the
239
+ # bit width of the largest argument type.
240
+ def make_depth(depth)
241
+ if depth then
242
+ @depth = depth
243
+ else
244
+ # There is no default depth, use the heuristic that the
245
+ # depth is more or less equal to the bit width of the
246
+ # largest argument type.
247
+ @depth = @funcE.each_argT.map {|t| t.width }.max
248
+ end
249
+ # Resize the stackes according to the depth.
250
+ @stack_sigs.each do |sig|
251
+ sig.type.instance_variable_set(:@range,0..@depth-1)
252
+ end
253
+ @stack_ptr.type.instance_variable_set(:@range,(@depth+1).width-1..0)
254
+ end
255
+
256
+
257
+
258
+ # Builds the code of the function.
259
+ # Returns the last state of the buit function, will serve
260
+ # for computing the return state of the first call.
261
+ def build
262
+ # Saves the current function to detect recursion.
263
+ @@current_stack.push(self)
264
+
265
+ # Get the body.
266
+ body = @funcE.body
267
+
268
+ # Create a state starting the function.
269
+ SequencerT.current.step
270
+
271
+ # Get the arguments.
272
+ args = (@argsIdx...(@argsIdx+body.arity)).map {|idx| self.peek(idx) }
273
+ # Place the body.
274
+ # SequencerT.current.instance_exec(*args,&body)
275
+ HDLRuby::High.top_user.instance_exec(*args,&body)
276
+ # # Free the stack of current frame.
277
+ # Moved to return...
278
+ # self.pop_all
279
+
280
+ # Create a state for returning.
281
+ st = self.make_return
282
+
283
+ # The function is built, remove it from recursion detection..
284
+ @@current_stack.pop
285
+
286
+ return st
287
+ end
288
+
289
+ # Call the function with arguments +args+ for the first time.
290
+ def first_call(*args)
291
+ # # Create a state for the call.
292
+ # call_state = SequencerT.current.step
293
+
294
+ # Push a new frame.
295
+ self.push_all
296
+
297
+ # Adds the arguments and the return state to the current stack frame.
298
+ args.each_with_index { |arg,i| self.poke(@argsIdx + i,arg) }
299
+ # The return is set afterward when the end of the function is
300
+ # known, since the return position for the first call is just
301
+ # after it.
302
+ # self.poke(@returnIdx,call_state.value + 1)
303
+
304
+ # Create a state for the call.
305
+ call_state = SequencerT.current.step
306
+
307
+
308
+ # Get the state value of the function: it is the state
309
+ # following the first function call.
310
+ func_state_value = call_state.value + ONE
311
+ # Do the call.
312
+ call_state.gotos << proc do
313
+ HDLRuby::High.top_user.instance_exec do
314
+ next_state_sig <= func_state_value
315
+ end
316
+ end
317
+
318
+ # Sets the state of the first function call.
319
+ @state = call_state
320
+
321
+ # Return the state for inserting the push of the return state.
322
+ return call_state
323
+ end
324
+
325
+ # Call the function with arguments +args+ for recursion.
326
+ def recurse_call(*args)
327
+ # # create a state for the call.
328
+ # call_state = SequencerT.current.step
329
+
330
+ # Get the variables for handling the stack overflow.
331
+ stack_ptr = @stack_ptr
332
+ depth = @depth
333
+ argsIdx = @argsIdx
334
+ this = self
335
+
336
+ # Adds the argument to the stack if no overflow.
337
+ HDLRuby::High.top_user.hif(stack_ptr < depth) do
338
+ # hprint("stack_ptr=",stack_ptr," depth=",depth,"\n")
339
+ # Adds the arguments and the return state to the current stack frame.
340
+ # Since not pushed the stack yet for not loosing the previous
341
+ # arguments, add +1 to the offset when poking the new arguments.
342
+ # args.each_with_index { |arg,i| self.poke(@argsIdx + i,arg,1) }
343
+ args.each_with_index { |arg,i| this.poke(argsIdx + i,arg,ONE) }
344
+ end
345
+
346
+ # Push a new frame.
347
+ self.push_all
348
+
349
+ # create a state for the call.
350
+ call_state = SequencerT.current.step
351
+
352
+ # Prepare the handling of overflow
353
+ call_state_value = call_state.value
354
+ overflow = @funcE.overflow
355
+ if overflow then
356
+ HDLRuby::High.top_user.hif(stack_ptr > depth) do
357
+ HDLRuby::High.top_user.instance_exec(&overflow)
358
+ end
359
+ end
360
+
361
+ # Get the state value of the function: it is the state
362
+ # following the first function call.
363
+ func_state_value = @state.value + ONE
364
+ # Do the call.
365
+ call_state.gotos << proc do
366
+ HDLRuby::High.top_user.instance_exec do
367
+ hif(stack_ptr <= depth) do
368
+ next_state_sig <= func_state_value
369
+ end
370
+ helse do
371
+ # Overflow! Skip the call.
372
+ next_state_sig <= call_state_value + ONE
373
+ # if overflow then
374
+ # # There is some overflow code to execute.
375
+ # HDLRuby::High.top_user.instance_exec(&overflow)
376
+ # end
377
+ end
378
+ end
379
+ end
380
+
381
+ return call_state
382
+ end
383
+
384
+ # Methods for handling the recursions and stacks.
385
+
386
+
387
+ ## Check if the current function call with eigen +funcE+ would be
388
+ # recursive or not.
389
+ def self.recursion(funcE)
390
+ # puts "recursion with funcE=#{funcE}"
391
+ return @@current_stack.find {|funcI| funcI.funcE == funcE }
392
+ end
393
+
394
+ ## Create a stack for elements of types +typ+.
395
+ def make_stack(typ)
396
+ # Create the signal array representing the stack.
397
+ depth = @depth
398
+ # puts "make stack with @depth=#{@depth}"
399
+ stack_sig = nil
400
+ name = @funcE.name
401
+ HDLRuby::High.cur_system.open do
402
+ stack_sig = typ[-depth].inner(
403
+ HDLRuby.uniq_name("#{name}_stack"))
404
+ end
405
+ # Add it to the list of stacks to handle.
406
+ @stack_sigs << stack_sig
407
+
408
+ # Returns the index of the newly created stack.
409
+ return @stack_sigs.size - ONE
410
+ end
411
+
412
+ ## Pushes a new frame to the top of the stacks.
413
+ def push_all
414
+ # HDLRuby::High.cur_system.hprint("push_all\n")
415
+ @stack_ptr <= @stack_ptr + ONE
416
+ end
417
+
418
+ ## Remove the top frame from the stacks.
419
+ def pop_all
420
+ # HDLRuby::High.cur_system.hprint("pop_all\n")
421
+ @stack_ptr <= @stack_ptr - ONE
422
+ end
423
+
424
+ ## Get a value from the top of stack number +idx+
425
+ # If +off+ is the offeset in the stack.
426
+ def peek(idx, off = 0)
427
+ return @stack_sigs[idx][(@stack_ptr-ONE)+off]
428
+ end
429
+
430
+ ## Sets value +val+ to the top of stack number +idx+.
431
+ # If +off+ is the offeset in the stack.
432
+ def poke(idx,val, off = 0)
433
+ # puts "idx=#{idx} val=#{val} sig=#{@stack_sigs[idx].name}"
434
+ @stack_sigs[idx][@stack_ptr-ONE+off] <= val
435
+ end
436
+
437
+ ## Access the return value signal.
438
+ def return_value
439
+ # return @stack_sigs[@returnValIdx][@stack_ptr-1]
440
+ @returnValue
441
+ end
442
+
443
+ ## Creates a return point with value +val+.
444
+ # Returns the created state.
445
+ #
446
+ # NOTE: when val is nil, no return value is provided.
447
+ def make_return(val = nil)
448
+ SequencerT.current.step
449
+ # puts "make_return with val=#{val}"
450
+ # Update the type of the return value.
451
+ if val then
452
+ # Update the type.
453
+ @returnValue.instance_variable_set(:@type, @returnValue.type.resolve(val.to_expr.type))
454
+ # Sets the return value if any.
455
+ self.return_value <= val
456
+ end
457
+ # Create the state for the return command.
458
+ state = SequencerT.current.step
459
+ # Get the return state value.
460
+ # ret_state_value = self.peek(@returnIdx, HDLRuby::High.top_user.mux(@stack_ptr < @depth,-1,0))
461
+ # Peek before the stack pointer value to account from the fact that
462
+ # the pop is performed beforehand.
463
+ ret_state_value = self.peek(@returnIdx, HDLRuby::High.top_user.mux(@stack_ptr < @depth,ZERO,ONE))
464
+ # Return.
465
+ this = self
466
+ state.gotos << proc do
467
+ HDLRuby::High.top_user.instance_exec do
468
+ # Set the next state.
469
+ next_state_sig <= ret_state_value
470
+ # # Pop must be place after setting the return state.
471
+ # this.pop_all
472
+ end
473
+ end
474
+ # Pop (done at clock edge, hence before the update of the state).
475
+ old_code = state.code
476
+ state.code = proc do
477
+ old_code.call
478
+ HDLRuby::High.top_user.instance_exec do
479
+ this.pop_all
480
+ end
481
+ end
482
+
483
+ return state
484
+ end
485
+ end
486
+
487
+
488
+
489
+
490
+ ## Remplement make_inners of block to support declaration within function.
491
+
492
+
493
+ class HDLRuby::High::Block
494
+ alias_method :old_make_inners, :make_inners
495
+
496
+ def make_inners(typ,*names)
497
+ res = nil
498
+ if SequencerFunctionI.current then
499
+ unames = names.map {|name| HDLRuby.uniq_name(name) }
500
+ res = HDLRuby::High.cur_scope.make_inners(typ, *unames)
501
+ names.zip(unames).each do |name,uname|
502
+ HDLRuby::High.space_reg(name) { send(uname) }
503
+ end
504
+ else
505
+ res = self.old_make_inners(typ,*names)
506
+ end
507
+ return res
508
+ end
509
+ end
510
+
511
+
512
+
513
+
514
+ # Declares a sequencer function named +name+ using +ruby_block+ as body.
515
+ # You can specify a stack depth with +depth+ argument and a HDLRuby
516
+ # block to execute in case of stack overflow with the +overflow+ argument.
517
+ def sdef(name, depth=nil, overflow = nil, &ruby_block)
518
+ # Create the function.
519
+ funcT = SequencerFunctionT.new(name,depth,overflow,&ruby_block)
520
+ # Register it for calling.
521
+ if HDLRuby::High.in_system? then
522
+ define_singleton_method(name.to_sym) do |*args|
523
+ funcT.call(*args)
524
+ end
525
+ else
526
+ define_method(name.to_sym) do |*args|
527
+ funcT.call(*args)
528
+ end
529
+ end
530
+ # Return the create function.
531
+ funcT
532
+ end
533
+
534
+ # Returns value +val+ from a sequencer function.
535
+ def sreturn(val)
536
+ # HDLRuby::High.top_user.hprint("sreturn\n")
537
+ # Get the top function.
538
+ funcI = SequencerFunctionI.current
539
+ unless funcI then
540
+ raise "Cannot return since outside a function."
541
+ end
542
+ # Applies the return on it.
543
+ funcI.make_return(val)
544
+ end
545
+
546
+ end
@@ -9,4 +9,6 @@ require 'std/fixpoint.rb'
9
9
  require 'std/decoder.rb'
10
10
  require 'std/fsm.rb'
11
11
  require 'std/sequencer.rb'
12
+ require 'std/sequencer_channel.rb'
12
13
  require 'std/sequencer_sync.rb'
14
+ require 'std/sequencer_func.rb'
@@ -1,3 +1,3 @@
1
1
  module HDLRuby
2
- VERSION = "3.0.0"
2
+ VERSION = "3.2.0"
3
3
  end