HDLRuby 3.0.0 → 3.1.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.
- 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