HDLRuby 2.11.12 → 3.1.0

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