HDLRuby 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +139 -79
- data/lib/HDLRuby/hdr_samples/constant_in_function.rb +2 -1
- data/lib/HDLRuby/hdr_samples/with_ref_expr.rb +30 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer.rb +32 -37
- data/lib/HDLRuby/hdr_samples/with_sequencer_enumerable.rb +103 -69
- data/lib/HDLRuby/hdr_samples/with_sequencer_enumerator.rb +10 -10
- data/lib/HDLRuby/hdr_samples/with_sequencer_func.rb +63 -0
- data/lib/HDLRuby/hdrcc.rb +1 -1
- data/lib/HDLRuby/hruby_high.rb +23 -5
- data/lib/HDLRuby/hruby_low_without_subsignals.rb +50 -11
- data/lib/HDLRuby/hruby_types.rb +5 -5
- data/lib/HDLRuby/hruby_values.rb +7 -7
- data/lib/HDLRuby/hruby_verilog.rb +101 -17
- data/lib/HDLRuby/hruby_verilog_name.rb +49 -42
- data/lib/HDLRuby/std/fsm.rb +10 -1
- data/lib/HDLRuby/std/sequencer.rb +281 -53
- data/lib/HDLRuby/std/sequencer_func.rb +533 -0
- data/lib/HDLRuby/std/std.rb +1 -0
- data/lib/HDLRuby/version.rb +1 -1
- data/tuto/tutorial_sw.md +267 -61
- metadata +5 -3
- data/lib/HDLRuby/hdr_samples/with_register_stack.rb +0 -150
@@ -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
|
data/lib/HDLRuby/std/std.rb
CHANGED
data/lib/HDLRuby/version.rb
CHANGED