HDLRuby 3.6.1 → 3.7.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 +189 -1
- data/lib/HDLRuby/hdr_samples/ruby_program/with_sw_hruby.rb +59 -0
- data/lib/HDLRuby/hdr_samples/ruby_program/with_sw_hruby_hruby_test.rb +74 -0
- data/lib/HDLRuby/hdr_samples/with_program_ruby.rb +8 -1
- data/lib/HDLRuby/hruby_high.rb +1 -1
- data/lib/HDLRuby/hruby_low.rb +2 -1
- data/lib/HDLRuby/hruby_rcsim.rb +4 -0
- data/lib/HDLRuby/std/sequencer_sw.rb +2825 -0
- data/lib/HDLRuby/ui/hruby_board.rb +28 -1
- data/lib/HDLRuby/version.rb +1 -1
- metadata +6 -3
@@ -0,0 +1,2825 @@
|
|
1
|
+
require "hruby_types.rb"
|
2
|
+
|
3
|
+
module RubyHDL
|
4
|
+
end
|
5
|
+
|
6
|
+
module RubyHDL::High
|
7
|
+
|
8
|
+
##
|
9
|
+
# SW implementation of the Standard HDLRuby::High library:
|
10
|
+
# sequencer generator.
|
11
|
+
# The idea is to be able to write sw-like sequential code.
|
12
|
+
#
|
13
|
+
########################################################################
|
14
|
+
|
15
|
+
|
16
|
+
@@absoluteCounter = -1 # The absolute name counter.
|
17
|
+
|
18
|
+
@@uniq_names = Set.new(Symbol.all_symbols.map {|sym| sym.to_s})
|
19
|
+
|
20
|
+
# Generates an absolute uniq name.
|
21
|
+
def self.uniq_name(base = "")
|
22
|
+
@@absoluteCounter += 1
|
23
|
+
name = base.to_s + ":#{@@absoluteCounter}"
|
24
|
+
if @@uniq_names.include?(name) then
|
25
|
+
# The symbol exists, try again.
|
26
|
+
return self.uniq_name
|
27
|
+
else
|
28
|
+
@@uniq_names.add(name)
|
29
|
+
return name.to_sym
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
# Describes a SW implementation of the top block.
|
36
|
+
# It cannot contain any statement, but can register objects.
|
37
|
+
class SblockTop
|
38
|
+
using RubyHDL::High
|
39
|
+
|
40
|
+
# Create a new top block.
|
41
|
+
def initialize
|
42
|
+
# Initialize the table of callable procs from outside.
|
43
|
+
@callables = { }
|
44
|
+
# Initialize the list of signals declared in this block.
|
45
|
+
@signals = []
|
46
|
+
end
|
47
|
+
|
48
|
+
# The sequencer of the block: none since top Sblock for globals.
|
49
|
+
def sequencer
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
|
53
|
+
# Generate inner signals with type +type+ and names from +names+ list.
|
54
|
+
def make_inners(type,*names)
|
55
|
+
type = type.to_type
|
56
|
+
last_sig = nil
|
57
|
+
names.each do |name|
|
58
|
+
name = name.to_sym
|
59
|
+
# Create and add the signal.
|
60
|
+
sig = SignalI.new(type,name)
|
61
|
+
@signals << sig
|
62
|
+
# Register it.
|
63
|
+
self.register(name) { sig }
|
64
|
+
last_sig = sig
|
65
|
+
end
|
66
|
+
return last_sig
|
67
|
+
end
|
68
|
+
|
69
|
+
# Register a new object named +name+ generated by +ruby_block+.
|
70
|
+
def register(name,&ruby_block)
|
71
|
+
# Add a way to call it from the stack of SW blocks.
|
72
|
+
::Object.define_method(name) do
|
73
|
+
RubyHDL::High.call_sblock(name)
|
74
|
+
end
|
75
|
+
# Add a method for accessing the object.
|
76
|
+
# self.define_singleton_method(name,&ruby_block)
|
77
|
+
res = ruby_block.call
|
78
|
+
@callables[name] = ruby_block
|
79
|
+
end
|
80
|
+
|
81
|
+
# Tell if a method is callable from there.
|
82
|
+
def callable?(m)
|
83
|
+
return @callables.key?(m)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Call a method from there.
|
87
|
+
def callable(m,*args,&ruby_block)
|
88
|
+
return @callables[m].call(*args,&ruby_block)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Iterate on the signal declared in the block.
|
92
|
+
def each_signal(&ruby_block)
|
93
|
+
return to_enum(:each_signal) unless ruby_block
|
94
|
+
@signals.each(&ruby_block)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
# The stack of SW blocks.
|
100
|
+
SBLOCK_STACK = [ SblockTop.new ]
|
101
|
+
|
102
|
+
def self.global_sblock
|
103
|
+
SBLOCK_STACK[0]
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.top_sblock
|
107
|
+
SBLOCK_STACK[-1]
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.push_sblock(sblock)
|
111
|
+
SBLOCK_STACK << sblock
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.pop_sblock
|
115
|
+
SBLOCK_STACK.pop
|
116
|
+
end
|
117
|
+
|
118
|
+
# Calling a method from the stack.
|
119
|
+
def self.call_sblock(m,*args,&ruby_block)
|
120
|
+
SBLOCK_STACK.reverse_each do |sblock|
|
121
|
+
if sblock.callable?(m) then
|
122
|
+
# return sblock.callable(m,*args,&ruby_block)
|
123
|
+
res = sblock.callable(m,*args,&ruby_block)
|
124
|
+
return res
|
125
|
+
end
|
126
|
+
end
|
127
|
+
# Method not found.
|
128
|
+
method_missing(m,*args,&ruby_block)
|
129
|
+
end
|
130
|
+
|
131
|
+
# # Handling of new names.
|
132
|
+
# class ::Object
|
133
|
+
# alias_method :old_method_missing, :method_missing
|
134
|
+
|
135
|
+
# def method_missing(m, *args, &ruby_block)
|
136
|
+
# # print "method_missing in class=#{self.class} with m=#{m}\n"
|
137
|
+
# # Not a value, but maybe it is in the stack of SW blocks
|
138
|
+
# SBLOCK_STACK.reverse_each do |sblock|
|
139
|
+
# if sblock.respond_to?(m) then
|
140
|
+
# return sblock.send(m,*args,&ruby_block)
|
141
|
+
# end
|
142
|
+
# end
|
143
|
+
# # puts "here: #{m}"
|
144
|
+
# # No, true error
|
145
|
+
# self.old_method_missing(m,*args,&ruby_block)
|
146
|
+
# end
|
147
|
+
# end
|
148
|
+
|
149
|
+
|
150
|
+
# The translation of operators into ruby code.
|
151
|
+
RUBY_OPERATOR = {
|
152
|
+
# Unary operators.
|
153
|
+
:"-@" => "-(%s)", :"+@" => "+(%s)", :"~" => "~(%s)",
|
154
|
+
:abs => "(%s).abs",
|
155
|
+
:boolean => "%s", :bit => "%s",
|
156
|
+
:signed => "%s", :unsigned => "(%s) & 0xFFFFFFFFFFFFFFFF",
|
157
|
+
|
158
|
+
# Binary operators.
|
159
|
+
:"+" => "(%s)+(%s)", :"-" => "(%s)-(%s)", :"*" => "(%s)*(%s)",
|
160
|
+
:"/" => "(%s)/(%s)", :"%" => "(%s)%%(%s)", :"**" => "(%s)**(%s)",
|
161
|
+
:"&" => "(%s)&(%s)", :"|" => "(%s)|(%s)", :"^" => "(%s)^(%s)",
|
162
|
+
:"<<" => "(%s)<<(%s)", :">>" => "(%s)>>(%s)",
|
163
|
+
:"==" => "(%s)==(%s)", :"!=" => "(%s)!=(%s)",
|
164
|
+
:"<" => "(%s)<(%s)", :">" => "(%s)>(%s)",
|
165
|
+
:"<=" => "(%s)<=(%s)",:">=" => "(%s)>=(%s)"
|
166
|
+
}
|
167
|
+
|
168
|
+
|
169
|
+
|
170
|
+
# Module adding functionalities to object including the +seach+ method.
|
171
|
+
module SEnumerable
|
172
|
+
|
173
|
+
# Iterator on each of the elements in range +rng+.
|
174
|
+
# *NOTE*:
|
175
|
+
# - Stop iteration when the end of the range is reached or when there
|
176
|
+
# are no elements left
|
177
|
+
# - This is not a method from Ruby but one specific for hardware where
|
178
|
+
# creating a array is very expensive.
|
179
|
+
def seach_range(rng,&ruby_block)
|
180
|
+
self.seach.seach_range(rng,&ruby_block)
|
181
|
+
end
|
182
|
+
|
183
|
+
# Tell if all the elements respect a given criterion given either
|
184
|
+
# as +arg+ or as block.
|
185
|
+
def sall?(arg = nil,&ruby_block)
|
186
|
+
self.seach.sall?(arg,&ruby_block)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Tell if any of the elements respects a given criterion given either
|
190
|
+
# as +arg+ or as block.
|
191
|
+
def sany?(arg = nil,&ruby_block)
|
192
|
+
self.seach.sany?(arg,&ruby_block)
|
193
|
+
end
|
194
|
+
|
195
|
+
# Returns an SEnumerator generated from current enumerable and +arg+
|
196
|
+
def schain(arg)
|
197
|
+
self.seach.schain(arg)
|
198
|
+
end
|
199
|
+
|
200
|
+
# HW implementation of the Ruby chunk.
|
201
|
+
# NOTE: to do, or may be not.
|
202
|
+
def schunk(*args,&ruby_block)
|
203
|
+
raise "schunk is not supported yet."
|
204
|
+
end
|
205
|
+
|
206
|
+
# HW implementation of the Ruby chunk_while.
|
207
|
+
# NOTE: to do, or may be not.
|
208
|
+
def schunk_while(*args,&ruby_block)
|
209
|
+
raise "schunk_while is not supported yet."
|
210
|
+
end
|
211
|
+
|
212
|
+
# Returns a vector containing the execution result of the given block
|
213
|
+
# on each element. If no block is given, return an SEnumerator.
|
214
|
+
# NOTE: be carful that the resulting vector can become huge if there
|
215
|
+
# are many element.
|
216
|
+
def smap(&ruby_block)
|
217
|
+
self.seach.smap(&ruby_block)
|
218
|
+
end
|
219
|
+
|
220
|
+
# HW implementation of the Ruby flat_map.
|
221
|
+
# NOTE: actually due to the way HDLRuby handles vectors, should work
|
222
|
+
# like smap
|
223
|
+
def sflat_map(&ruby_block)
|
224
|
+
self.seach.sflat_map(&ruby_block)
|
225
|
+
end
|
226
|
+
|
227
|
+
# HW implementation of the Ruby compact, but remove 0 values instead
|
228
|
+
# on nil (since nil that does not have any meaning in HW).
|
229
|
+
def scompact
|
230
|
+
self.seach.scompact(&ruby_block)
|
231
|
+
end
|
232
|
+
|
233
|
+
|
234
|
+
# WH implementation of the Ruby count.
|
235
|
+
def scount(obj = nil, &ruby_block)
|
236
|
+
self.seach.scount(obj,&ruby_block)
|
237
|
+
end
|
238
|
+
|
239
|
+
# HW implementation of the Ruby cycle.
|
240
|
+
def scycle(n = nil,&ruby_block)
|
241
|
+
self.seach.scycle(n,&ruby_block)
|
242
|
+
end
|
243
|
+
|
244
|
+
# HW implementation of the Ruby find.
|
245
|
+
# NOTE: contrary to Ruby, if_none_proc is mandatory since there is no
|
246
|
+
# nil in HW. Moreover, the argument can also be a value.
|
247
|
+
def sfind(if_none_proc, &ruby_block)
|
248
|
+
self.seach.sfind(if_non_proc,&ruby_block)
|
249
|
+
end
|
250
|
+
|
251
|
+
# HW implementation of the Ruby drop.
|
252
|
+
def sdrop(n)
|
253
|
+
self.seach.sdrop(n)
|
254
|
+
end
|
255
|
+
|
256
|
+
# HW implementation of the Ruby drop_while.
|
257
|
+
def sdrop_while(&ruby_block)
|
258
|
+
self.seach.sdrop_while(n)
|
259
|
+
end
|
260
|
+
|
261
|
+
# HW implementation of the Ruby each_cons
|
262
|
+
def seach_cons(n,&ruby_block)
|
263
|
+
self.seach.seach_cons(n,&ruby_block)
|
264
|
+
end
|
265
|
+
|
266
|
+
# HW implementation of the Ruby each_entry.
|
267
|
+
# NOTE: to do, or may be not.
|
268
|
+
def seach_entry(*args,&ruby_block)
|
269
|
+
raise "seach_entry is not supported yet."
|
270
|
+
end
|
271
|
+
|
272
|
+
# HW implementation of the Ruby each_slice
|
273
|
+
def seach_slice(n,&ruby_block)
|
274
|
+
self.seach.seach_slice(n,&ruby_block)
|
275
|
+
end
|
276
|
+
|
277
|
+
# HW implementation of the Ruby each_with_index.
|
278
|
+
def seach_with_index(*args,&ruby_block)
|
279
|
+
self.seach.swith_index(*args,&ruby_block)
|
280
|
+
end
|
281
|
+
|
282
|
+
# HW implementation of the Ruby each_with_object.
|
283
|
+
def seach_with_object(obj,&ruby_block)
|
284
|
+
self.seach.swith_object(obj,&ruby_block)
|
285
|
+
end
|
286
|
+
|
287
|
+
# HW implementation of the Ruby to_a.
|
288
|
+
def sto_a
|
289
|
+
self.seach.sto_a
|
290
|
+
end
|
291
|
+
|
292
|
+
# HW implementation of the Ruby select.
|
293
|
+
def sselect(&ruby_block)
|
294
|
+
self.seach.sselect(&ruby_block)
|
295
|
+
end
|
296
|
+
|
297
|
+
# HW implementation of the Ruby find_index.
|
298
|
+
def sfind_index(obj = nil, &ruby_block)
|
299
|
+
self.seach.sfind_index(obj,&ruby_block)
|
300
|
+
end
|
301
|
+
|
302
|
+
# HW implementation of the Ruby first.
|
303
|
+
def sfirst(n=1)
|
304
|
+
self.seach.sfirst(n)
|
305
|
+
end
|
306
|
+
|
307
|
+
# HW implementation of the Ruby grep.
|
308
|
+
# NOTE: to do, or may be not.
|
309
|
+
def sgrep(*args,&ruby_block)
|
310
|
+
raise "sgrep is not supported yet."
|
311
|
+
end
|
312
|
+
|
313
|
+
# HW implementation of the Ruby grep_v.
|
314
|
+
# NOTE: to do, or may be not.
|
315
|
+
def sgrep_v(*args,&ruby_block)
|
316
|
+
raise "sgrep_v is not supported yet."
|
317
|
+
end
|
318
|
+
|
319
|
+
# HW implementation of the Ruby group_by.
|
320
|
+
# NOTE: to do, or may be not.
|
321
|
+
def sgroup_by(*args,&ruby_block)
|
322
|
+
raise "sgroup_by is not supported yet."
|
323
|
+
end
|
324
|
+
|
325
|
+
# HW implementation of the Ruby include?
|
326
|
+
def sinclude?(obj)
|
327
|
+
return self.seach.sinclude?(obj)
|
328
|
+
end
|
329
|
+
|
330
|
+
# HW implementation of the Ruby inject.
|
331
|
+
def sinject(*args,&ruby_block)
|
332
|
+
return self.seach.sinject(*args,&ruby_block)
|
333
|
+
end
|
334
|
+
|
335
|
+
# HW implementation of the Ruby reduce.
|
336
|
+
def sreduce(*args,&ruby_block)
|
337
|
+
return self.seach.sreduce(*args,&ruby_block)
|
338
|
+
end
|
339
|
+
|
340
|
+
# HW implementation of the Ruby lazy.
|
341
|
+
# NOTE: to do, or may be not.
|
342
|
+
def slazy(*args,&ruby_block)
|
343
|
+
raise "slazy is not supported yet."
|
344
|
+
end
|
345
|
+
|
346
|
+
# HW implementation of the Ruby max.
|
347
|
+
def smax(n = nil, &ruby_block)
|
348
|
+
return self.seach.smax(n,&ruby_block)
|
349
|
+
end
|
350
|
+
|
351
|
+
# HW implementation of the Ruby max_by.
|
352
|
+
def smax_by(n = nil, &ruby_block)
|
353
|
+
return self.seach.smax_by(n,&ruby_block)
|
354
|
+
end
|
355
|
+
|
356
|
+
# HW implementation of the Ruby min.
|
357
|
+
def smin(n = nil, &ruby_block)
|
358
|
+
return self.seach.smin(n,&ruby_block)
|
359
|
+
end
|
360
|
+
|
361
|
+
# HW implementation of the Ruby min_by.
|
362
|
+
def smin_by(n = nil, &ruby_block)
|
363
|
+
return self.seach.smin_by(n,&ruby_block)
|
364
|
+
end
|
365
|
+
|
366
|
+
# HW implementation of the Ruby minmax.
|
367
|
+
def sminmax(&ruby_block)
|
368
|
+
return self.seach.sminmax(&ruby_block)
|
369
|
+
end
|
370
|
+
|
371
|
+
# HW implementation of the Ruby minmax_by.
|
372
|
+
def sminmax_by(&ruby_block)
|
373
|
+
return self.seach.sminmax_by(&ruby_block)
|
374
|
+
end
|
375
|
+
|
376
|
+
# Tell if none of the elements respects a given criterion given either
|
377
|
+
# as +arg+ or as block.
|
378
|
+
def snone?(arg = nil,&ruby_block)
|
379
|
+
return self.seach.snone?(arg,&ruby_block)
|
380
|
+
end
|
381
|
+
|
382
|
+
# Tell if one and only one of the elements respects a given criterion
|
383
|
+
# given either as +arg+ or as block.
|
384
|
+
def sone?(arg = nil,&ruby_block)
|
385
|
+
return self.seach.sone?(arg,&ruby_block)
|
386
|
+
end
|
387
|
+
|
388
|
+
# HW implementation of the Ruby partition.
|
389
|
+
# NOTE: to do, or may be not.
|
390
|
+
def spartition(*args,&ruby_block)
|
391
|
+
raise "spartition is not supported yet."
|
392
|
+
end
|
393
|
+
|
394
|
+
# HW implementatiob of the Ruby reject.
|
395
|
+
def sreject(&ruby_block)
|
396
|
+
return self.seach.sreject(&ruby_block)
|
397
|
+
end
|
398
|
+
|
399
|
+
# HW implementatiob of the Ruby reverse_each.
|
400
|
+
def sreverse_each(*args,&ruby_block)
|
401
|
+
return self.seach.sreverse_each(*args,&ruby_block)
|
402
|
+
end
|
403
|
+
|
404
|
+
# HW implementation of the Ruby slice_after.
|
405
|
+
# NOTE: to do, or may be not.
|
406
|
+
def sslice_after(pattern = nil,&ruby_block)
|
407
|
+
raise "sslice_after is not supported yet."
|
408
|
+
end
|
409
|
+
|
410
|
+
# HW implementation of the Ruby slice_before.
|
411
|
+
# NOTE: to do, or may be not.
|
412
|
+
def sslice_before(*args,&ruby_block)
|
413
|
+
raise "sslice_before is not supported yet."
|
414
|
+
end
|
415
|
+
|
416
|
+
# HW implementation of the Ruby slice_when.
|
417
|
+
# NOTE: to do, or may be not.
|
418
|
+
def sslice_when(*args,&ruby_block)
|
419
|
+
raise "sslice_before is not supported yet."
|
420
|
+
end
|
421
|
+
|
422
|
+
# Merge two arrays in order, for ssort only.
|
423
|
+
def ssort_merge(arI, arO, first, middle, last, &ruby_block)
|
424
|
+
return self.seach.ssort_merge(arI,arO,first,middle,last,&ruby_block)
|
425
|
+
end
|
426
|
+
|
427
|
+
# HW implementation of the Ruby sort.
|
428
|
+
def ssort(&ruby_block)
|
429
|
+
return self.seach.ssort(&ruby_block)
|
430
|
+
end
|
431
|
+
|
432
|
+
# HW implementation of the Ruby sort.
|
433
|
+
def ssort_by(&ruby_block)
|
434
|
+
return self.seach.ssort_by(&ruby_block)
|
435
|
+
end
|
436
|
+
|
437
|
+
# HW implementation of the Ruby sum.
|
438
|
+
def ssum(initial_value = nil,&ruby_block)
|
439
|
+
return self.seach.ssum(initial_value,&ruby_block)
|
440
|
+
end
|
441
|
+
|
442
|
+
# The HW implementation of the Ruby take.
|
443
|
+
def stake(n)
|
444
|
+
return self.seach.stake(n)
|
445
|
+
end
|
446
|
+
|
447
|
+
# The HW implementation of the Ruby take_while.
|
448
|
+
def stake_while(&ruby_block)
|
449
|
+
return self.seach.stake_while(&ruby_block)
|
450
|
+
end
|
451
|
+
|
452
|
+
# HW implementation of the Ruby tally.
|
453
|
+
# NOTE: to do, or may be not.
|
454
|
+
def stally(h = nil)
|
455
|
+
raise "stally is not supported yet."
|
456
|
+
end
|
457
|
+
|
458
|
+
# HW implementation of the Ruby to_h.
|
459
|
+
# NOTE: to do, or may be not.
|
460
|
+
def sto_h(h = nil)
|
461
|
+
raise "sto_h is not supported yet."
|
462
|
+
end
|
463
|
+
|
464
|
+
# HW implementation of the Ruby uniq.
|
465
|
+
def suniq(&ruby_block)
|
466
|
+
return self.seach.suniq(&ruby_block)
|
467
|
+
end
|
468
|
+
|
469
|
+
# HW implementation of the Ruby zip.
|
470
|
+
# NOTE: for now szip is deactivated untile tuples are properly
|
471
|
+
# handled by HDLRuby.
|
472
|
+
def szip(obj,&ruby_block)
|
473
|
+
return self.seach.szip(obj,&ruby_block)
|
474
|
+
end
|
475
|
+
|
476
|
+
# Iterator on the +num+ next elements.
|
477
|
+
# *NOTE*:
|
478
|
+
# - Stop iteration when the end of the range is reached or when there
|
479
|
+
# are no elements left
|
480
|
+
# - This is not a method from Ruby but one specific for hardware where
|
481
|
+
# creating a array is very expensive.
|
482
|
+
def seach_nexts(num,&ruby_block)
|
483
|
+
return self.seach.snexts(num,&ruby_block)
|
484
|
+
end
|
485
|
+
|
486
|
+
end
|
487
|
+
|
488
|
+
|
489
|
+
# Modify String to act as ruby code generator.
|
490
|
+
refine ::String do
|
491
|
+
def to_ruby
|
492
|
+
self
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
|
497
|
+
# Modify Integer to act as value.
|
498
|
+
refine ::Integer do
|
499
|
+
def to_value
|
500
|
+
return Value.new(signed[32],self)
|
501
|
+
end
|
502
|
+
alias_method :to_expr, :to_value
|
503
|
+
|
504
|
+
# Enhance the Integer class with sequencer iterations.
|
505
|
+
|
506
|
+
# HW times iteration.
|
507
|
+
def stimes(&ruby_block)
|
508
|
+
self.to_value.stimes(&ruby_block)
|
509
|
+
end
|
510
|
+
|
511
|
+
# HW upto iteration.
|
512
|
+
def supto(val,&ruby_block)
|
513
|
+
self.to_value.supto(&ruby_block)
|
514
|
+
end
|
515
|
+
|
516
|
+
# HW downto iteration.
|
517
|
+
def sdownto(val,&ruby_block)
|
518
|
+
self.to_value.sdownto(&ruby_block)
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
# Modify Float to act as value.
|
523
|
+
refine ::Float do
|
524
|
+
def to_value
|
525
|
+
return Value.new(float[64],self)
|
526
|
+
end
|
527
|
+
alias_method :to_expr, :to_value
|
528
|
+
end
|
529
|
+
|
530
|
+
# Modify Range to support HW iterators.
|
531
|
+
refine ::Enumerable do
|
532
|
+
import_methods SEnumerable
|
533
|
+
# HW iteration on each element.
|
534
|
+
def seach(&ruby_block)
|
535
|
+
RubyHDL::High.top_sblock << SeachEnumerable.new(self,&ruby_block)
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
|
+
|
540
|
+
|
541
|
+
|
542
|
+
# Modify Array to build types.
|
543
|
+
refine ::Array do
|
544
|
+
|
545
|
+
# Convert to a type.
|
546
|
+
def to_type
|
547
|
+
# Compute the base type.
|
548
|
+
if self[0].is_a?(::Array) then
|
549
|
+
# Recurse build the base.
|
550
|
+
base = self[0].to_type
|
551
|
+
else
|
552
|
+
base = unsigned
|
553
|
+
end
|
554
|
+
# Generate the resulting type vector.
|
555
|
+
return TypeVector.new(:"",base,self[0])
|
556
|
+
end
|
557
|
+
|
558
|
+
# Generate signals from +names+.
|
559
|
+
def inner(*names)
|
560
|
+
# Generate the type.
|
561
|
+
type = self.to_type
|
562
|
+
# Generate the resulting signals.
|
563
|
+
return type.inner(*names)
|
564
|
+
end
|
565
|
+
end
|
566
|
+
|
567
|
+
|
568
|
+
|
569
|
+
# Describes a SW implementation of types.
|
570
|
+
|
571
|
+
##
|
572
|
+
# Describes a high-level data type.
|
573
|
+
#
|
574
|
+
# NOTE: by default a type is not specified.
|
575
|
+
class Type
|
576
|
+
using RubyHDL::High
|
577
|
+
include HDLRuby::Tprocess
|
578
|
+
|
579
|
+
# Type creation.
|
580
|
+
|
581
|
+
# Creates a new type named +name+.
|
582
|
+
def initialize(name = nil)
|
583
|
+
if name then
|
584
|
+
@name = name.to_sym
|
585
|
+
# Registers the name.
|
586
|
+
self.register(name)
|
587
|
+
end
|
588
|
+
end
|
589
|
+
|
590
|
+
# Type access
|
591
|
+
|
592
|
+
# Comparison for hash: structural comparison.
|
593
|
+
def eql?(obj)
|
594
|
+
return false unless obj.is_a?(Type)
|
595
|
+
return false unless @name.eql?(obj.name)
|
596
|
+
return true
|
597
|
+
end
|
598
|
+
|
599
|
+
# Hash function.
|
600
|
+
def hash
|
601
|
+
return [@name].hash
|
602
|
+
end
|
603
|
+
|
604
|
+
# Tells if the type signed.
|
605
|
+
def signed?
|
606
|
+
return false
|
607
|
+
end
|
608
|
+
|
609
|
+
# Tells if the type is unsigned.
|
610
|
+
def unsigned?
|
611
|
+
return false
|
612
|
+
end
|
613
|
+
|
614
|
+
# Tells if the type is fixed point.
|
615
|
+
def fixed?
|
616
|
+
return false
|
617
|
+
end
|
618
|
+
|
619
|
+
# Tells if the type is floating point.
|
620
|
+
def float?
|
621
|
+
return false
|
622
|
+
end
|
623
|
+
|
624
|
+
# Tells if the type is a leaf.
|
625
|
+
def leaf?
|
626
|
+
return false
|
627
|
+
end
|
628
|
+
|
629
|
+
# Tells if the type of of vector kind.
|
630
|
+
def vector?
|
631
|
+
return false
|
632
|
+
end
|
633
|
+
|
634
|
+
# Gets the bitwidth of the type, by default 0.
|
635
|
+
# Bit, signed, unsigned and Float base have a width of 1.
|
636
|
+
def width
|
637
|
+
if [:bit, :signed, :unsigned, :float ].include?(@name) then
|
638
|
+
return 1
|
639
|
+
else
|
640
|
+
return 0
|
641
|
+
end
|
642
|
+
end
|
643
|
+
|
644
|
+
# Gets the type max value if any.
|
645
|
+
# Default: not defined.
|
646
|
+
def max
|
647
|
+
raise AnyError, "No max value for type #{self}"
|
648
|
+
end
|
649
|
+
|
650
|
+
# Gets the type min value if any.
|
651
|
+
# Default: not defined.
|
652
|
+
def min
|
653
|
+
raise AnyError, "No min value for type #{self}"
|
654
|
+
end
|
655
|
+
|
656
|
+
# Get the direction of the type, little or big endian.
|
657
|
+
def direction
|
658
|
+
# By default, little endian.
|
659
|
+
return :little
|
660
|
+
end
|
661
|
+
|
662
|
+
# Tells if the type has a range.
|
663
|
+
def range?
|
664
|
+
return false
|
665
|
+
end
|
666
|
+
|
667
|
+
# Gets the range of the type, by default range is not defined.
|
668
|
+
def range
|
669
|
+
raise AnyError, "No range for type #{self}"
|
670
|
+
end
|
671
|
+
|
672
|
+
# Tells if the type has a base.
|
673
|
+
def base?
|
674
|
+
return false
|
675
|
+
end
|
676
|
+
|
677
|
+
# Gets the base type, by default base type is not defined.
|
678
|
+
def base
|
679
|
+
raise AnyError, "No base type for type #{self}"
|
680
|
+
end
|
681
|
+
|
682
|
+
# Tells if the type has sub types.
|
683
|
+
def types?
|
684
|
+
return false
|
685
|
+
end
|
686
|
+
|
687
|
+
# Tells if the type is regular (applies for tuples).
|
688
|
+
def regular?
|
689
|
+
return false
|
690
|
+
end
|
691
|
+
|
692
|
+
# Tells if the type has named sub types.
|
693
|
+
def struct?
|
694
|
+
return false
|
695
|
+
end
|
696
|
+
|
697
|
+
# Tells if the type is hierarchical.
|
698
|
+
def hierarchical?
|
699
|
+
return self.base? || self.types?
|
700
|
+
end
|
701
|
+
|
702
|
+
# Tell if +type+ is equivalent to current type.
|
703
|
+
#
|
704
|
+
# NOTE: type can be compatible while not being equivalent, please
|
705
|
+
# refer to `hruby_types.rb` for type compatibility.
|
706
|
+
def equivalent?(type)
|
707
|
+
# By default, types are equivalent iff they have the same name.
|
708
|
+
return (type.is_a?(Type) and self.name == type.name)
|
709
|
+
end
|
710
|
+
|
711
|
+
# Iterates over the types deeply if any.
|
712
|
+
def each_type_deep(&ruby_block)
|
713
|
+
# No ruby block? Return an enumerator.
|
714
|
+
return to_enum(:each_type_deep) unless ruby_block
|
715
|
+
# A ruby block? First apply it to current.
|
716
|
+
ruby_block.call(self)
|
717
|
+
# And that's all by default.
|
718
|
+
end
|
719
|
+
alias_method :each_deep, :each_type_deep
|
720
|
+
|
721
|
+
# Converts to a bit vector.
|
722
|
+
def to_vector
|
723
|
+
return TypeVector.new(:"", Bit, self.width-1..0)
|
724
|
+
end
|
725
|
+
|
726
|
+
# Tells htype has been included.
|
727
|
+
def htype?
|
728
|
+
return true
|
729
|
+
end
|
730
|
+
|
731
|
+
# Converts to a type.
|
732
|
+
# Returns self since it is already a type.
|
733
|
+
def to_type
|
734
|
+
return self
|
735
|
+
end
|
736
|
+
|
737
|
+
# Sets the +name+.
|
738
|
+
#
|
739
|
+
# NOTE: can only be done if the name is not already set.
|
740
|
+
def name=(name)
|
741
|
+
unless @name.empty? then
|
742
|
+
raise AnyError, "Name of type already set to: #{@name}."
|
743
|
+
end
|
744
|
+
# Checks and sets the name.
|
745
|
+
name = name.to_sym
|
746
|
+
if name.empty? then
|
747
|
+
raise AnyError, "Cannot set an empty name."
|
748
|
+
end
|
749
|
+
@name = name
|
750
|
+
# Registers the name.
|
751
|
+
self.register(name)
|
752
|
+
end
|
753
|
+
|
754
|
+
# Register the +name+ of the type.
|
755
|
+
def register(name)
|
756
|
+
# Sets the hdl-like access to the type.
|
757
|
+
obj = self # For using the right self within the proc
|
758
|
+
RubyHDL::High.top_sblock.register(name) { obj }
|
759
|
+
end
|
760
|
+
|
761
|
+
# Gets the type as left value.
|
762
|
+
#
|
763
|
+
# NOTE: used for asymetric types like TypeSystemI.
|
764
|
+
def left
|
765
|
+
# By default self.
|
766
|
+
self
|
767
|
+
end
|
768
|
+
|
769
|
+
# Gets the type as right value.
|
770
|
+
#
|
771
|
+
# NOTE: used for asymetric types like TypeSystemI.
|
772
|
+
def right
|
773
|
+
# By default self.
|
774
|
+
self
|
775
|
+
end
|
776
|
+
|
777
|
+
# Type creation.
|
778
|
+
|
779
|
+
# Declares a new type definition with +name+ equivalent to current one.
|
780
|
+
def typedef(name)
|
781
|
+
# Create the new type.
|
782
|
+
typ = TypeDef.new(name,self)
|
783
|
+
# Register it.
|
784
|
+
High.top_sblock.register(name) { typ }
|
785
|
+
# Return it.
|
786
|
+
return typ
|
787
|
+
end
|
788
|
+
|
789
|
+
# Creates a new vector type of range +rng+ and with current type as
|
790
|
+
# base.
|
791
|
+
def [](rng)
|
792
|
+
return TypeVector.new(:"",self,rng)
|
793
|
+
end
|
794
|
+
|
795
|
+
# SignalI creation through the type.
|
796
|
+
|
797
|
+
# # Declares high-level input signals named +names+ of the current type.
|
798
|
+
# def input(*names)
|
799
|
+
# High.top_sblock.make_inputs(self,*names)
|
800
|
+
# end
|
801
|
+
|
802
|
+
# # Declares high-level untyped output signals named +names+ of the
|
803
|
+
# # current type.
|
804
|
+
# def output(*names)
|
805
|
+
# # High.top_user.make_outputs(self.instantiate,*names)
|
806
|
+
# High.top_sblock.make_outputs(self,*names)
|
807
|
+
# end
|
808
|
+
|
809
|
+
# # Declares high-level untyped inout signals named +names+ of the
|
810
|
+
# # current type.
|
811
|
+
# def inout(*names)
|
812
|
+
# # High.top_user.make_inouts(self.instantiate,*names)
|
813
|
+
# High.top_sblock.make_inouts(self,*names)
|
814
|
+
# end
|
815
|
+
|
816
|
+
# Declares high-level untyped inner signals named +names+ of the
|
817
|
+
# current type.
|
818
|
+
def inner(*names)
|
819
|
+
RubyHDL::High.top_sblock.make_inners(self,*names)
|
820
|
+
end
|
821
|
+
|
822
|
+
# Declares high-level untyped constant signals by name and
|
823
|
+
# value given by +hsh+ of the current type.
|
824
|
+
def constant(hsh)
|
825
|
+
RubyHDL::High.top_sblock.make_constants(self,hsh)
|
826
|
+
end
|
827
|
+
|
828
|
+
# Computations of expressions
|
829
|
+
|
830
|
+
# Gets the computation method for +operator+.
|
831
|
+
def comp_operator(op)
|
832
|
+
return (op.to_s + ":C").to_sym
|
833
|
+
end
|
834
|
+
|
835
|
+
# Performs unary operation +operator+ on expression +expr+.
|
836
|
+
def unary(operator,expr)
|
837
|
+
# Look for a specific computation method.
|
838
|
+
comp = comp_operator(operator)
|
839
|
+
if self.respond_to?(comp) then
|
840
|
+
# Found, use it.
|
841
|
+
self.send(comp,expr)
|
842
|
+
else
|
843
|
+
# Not found, back to default computation.
|
844
|
+
expr.to_value.send(operator)
|
845
|
+
end
|
846
|
+
end
|
847
|
+
|
848
|
+
# Performs binary operation +operator+ on expressions +expr0+
|
849
|
+
# and +expr1+.
|
850
|
+
def binary(operator, expr0, expr1)
|
851
|
+
# Look for a specific computation method.
|
852
|
+
comp = comp_operator(operator)
|
853
|
+
if self.respond_to?(comp) then
|
854
|
+
# Found, use it.
|
855
|
+
self.send(comp,expr0,expr1)
|
856
|
+
else
|
857
|
+
# Not found, back to default computation.
|
858
|
+
expr0.to_value.send(operator,expr1)
|
859
|
+
end
|
860
|
+
end
|
861
|
+
|
862
|
+
# Redefinition of +operator+.
|
863
|
+
def define_operator(operator,&ruby_block)
|
864
|
+
# Ensure there is a block.
|
865
|
+
ruby_block = proc {} unless block_given?
|
866
|
+
# Register the operator as overloaded.
|
867
|
+
@overloads ||= {}
|
868
|
+
@overloads[operator] = ruby_block
|
869
|
+
# Set the new method for the operator.
|
870
|
+
self.define_singleton_method(comp_operator(operator)) do |*args|
|
871
|
+
# puts "Top user=#{HDLRuby::High.top_user}"
|
872
|
+
RubyHDL::High.top_sblock.sub(RubyHDL.uniq_name) do
|
873
|
+
ruby_block.call(*args)
|
874
|
+
end
|
875
|
+
end
|
876
|
+
end
|
877
|
+
|
878
|
+
# Redefinition of +operator+ when requiring the context to be passed
|
879
|
+
# as argument (normally only used internally).
|
880
|
+
def define_operator_with_context(operator,&ruby_block)
|
881
|
+
# Ensure there is a block.
|
882
|
+
ruby_block = proc {} unless block_given?
|
883
|
+
# Register the operator as overloaded.
|
884
|
+
@overloads ||= {}
|
885
|
+
@overloads[operator] = ruby_block
|
886
|
+
# Set the new method for the operator.
|
887
|
+
self.define_singleton_method(comp_operator(operator)) do |*args|
|
888
|
+
# puts "Top user=#{HDLRuby::High.top_user}"
|
889
|
+
RubyHDL::High.top_sblock.sub(RubyHDL.uniq_name) do
|
890
|
+
# It is assumed that the first argument of the ruby_block
|
891
|
+
# is the context in which it must be executed.
|
892
|
+
ruby_block.call(self,*args)
|
893
|
+
end
|
894
|
+
end
|
895
|
+
end
|
896
|
+
|
897
|
+
# Interates over the overloaded operators.
|
898
|
+
def each_overload(&ruby_block)
|
899
|
+
# No ruby block? Return an enumerator.
|
900
|
+
return to_enum(:each_overload) unless ruby_block
|
901
|
+
# A block? Apply it on each overload if any.
|
902
|
+
@overloads.each(&ruby_block) if @overloads
|
903
|
+
end
|
904
|
+
end
|
905
|
+
|
906
|
+
|
907
|
+
# Defines a basic type +name+.
|
908
|
+
def self.define_type(name)
|
909
|
+
name = name.to_sym
|
910
|
+
type = Type.new(name)
|
911
|
+
self.send(:define_method,name) { type }
|
912
|
+
return type
|
913
|
+
end
|
914
|
+
|
915
|
+
# The void type
|
916
|
+
Void = define_type(:void)
|
917
|
+
|
918
|
+
# The bit type.
|
919
|
+
Bit = define_type(:bit)
|
920
|
+
|
921
|
+
# The signed bit type.
|
922
|
+
Signed = define_type(:signed)
|
923
|
+
|
924
|
+
# The unsigned bit type.
|
925
|
+
Unsigned = define_type(:unsigned)
|
926
|
+
|
927
|
+
# The float bit type
|
928
|
+
Float = define_type(:float)
|
929
|
+
|
930
|
+
# The string type
|
931
|
+
StringT = define_type(:string)
|
932
|
+
|
933
|
+
|
934
|
+
##
|
935
|
+
# Describes a high-level type definition.
|
936
|
+
#
|
937
|
+
# NOTE: type definition are actually type with a name refering to another
|
938
|
+
# type (and equivalent to it).
|
939
|
+
class TypeDef < Type
|
940
|
+
# Type creation.
|
941
|
+
|
942
|
+
# Creates a new type definition named +name+ refering +type+.
|
943
|
+
def initialize(name,type)
|
944
|
+
# Initialize the type structure.
|
945
|
+
super(name)
|
946
|
+
# Set the referenced type.
|
947
|
+
@type = type.to_type
|
948
|
+
end
|
949
|
+
end
|
950
|
+
|
951
|
+
##
|
952
|
+
# Describes a high-level generic type definition.
|
953
|
+
#
|
954
|
+
# NOTE: this type does not correspond to any low-level type
|
955
|
+
class TypeGen < Type
|
956
|
+
# Type creation.
|
957
|
+
|
958
|
+
# Creates a new generic type definition producing a new type by
|
959
|
+
# executing +ruby_block+.
|
960
|
+
def initialize(name,&ruby_block)
|
961
|
+
# Initialize the type structure.
|
962
|
+
super(name)
|
963
|
+
# Sets the block to execute when instantiating the type.
|
964
|
+
@instance_proc = ruby_block
|
965
|
+
end
|
966
|
+
|
967
|
+
# Generates the type with +args+ generic parameters.
|
968
|
+
def generate(*args)
|
969
|
+
# Generate the resulting type.
|
970
|
+
gtype = RubyHDL::High.top_sblock.instance_exec(*args,&@instance_proc)
|
971
|
+
# Ensures a type has been produced.
|
972
|
+
gtype = gtype.to_type if gtype.respond_to?(:to_type)
|
973
|
+
unless gtype.is_a?(Type) then
|
974
|
+
raise AnyError, "Generic type #{self.name} did not produce a valid type: #{gtype.class}"
|
975
|
+
end
|
976
|
+
# Create a new type definition from it.
|
977
|
+
gtype = TypeDef.new(self.name.to_s + "_#{args.join(':')}",
|
978
|
+
gtype)
|
979
|
+
# Adds the possible overloaded operators.
|
980
|
+
self.each_overload do |op,ruby_block|
|
981
|
+
gtype.define_operator_with_context(op,&(RubyHDL::High.curry_with_context(*args,&ruby_block)))
|
982
|
+
end
|
983
|
+
# Returns the resulting type
|
984
|
+
return gtype
|
985
|
+
end
|
986
|
+
end
|
987
|
+
|
988
|
+
|
989
|
+
##
|
990
|
+
# Describes a vector type.
|
991
|
+
class TypeVector < Type
|
992
|
+
# The base type of the vector
|
993
|
+
attr_reader :base
|
994
|
+
|
995
|
+
# Tells if the type of of vector kind.
|
996
|
+
def vector?
|
997
|
+
return true
|
998
|
+
end
|
999
|
+
|
1000
|
+
# Tells if the type has a base.
|
1001
|
+
def base?
|
1002
|
+
return true
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
# The range of the vector.
|
1006
|
+
attr_reader :range
|
1007
|
+
|
1008
|
+
# Creates a new vector type named +name+ from +base+ type and with
|
1009
|
+
# +range+.
|
1010
|
+
# NOTE: if +range+ is a positive integer it is converted to
|
1011
|
+
# (range-1)..0, if it is a negative integer it is converted to
|
1012
|
+
# 0..(-range-1)
|
1013
|
+
def initialize(name,base,range)
|
1014
|
+
# Initialize the type.
|
1015
|
+
super(name)
|
1016
|
+
|
1017
|
+
# Check and set the base
|
1018
|
+
unless base.is_a?(Type)
|
1019
|
+
raise AnyError,
|
1020
|
+
"Invalid class for VectorType base: #{base.class}."
|
1021
|
+
end
|
1022
|
+
@base = base
|
1023
|
+
|
1024
|
+
# Check and set the range.
|
1025
|
+
if range.respond_to?(:to_i) then
|
1026
|
+
# Integer case: convert to 0..(range-1).
|
1027
|
+
range = range > 0 ? (range-1)..0 : 0..(-range-1)
|
1028
|
+
elsif
|
1029
|
+
# Other cases: assume there is a first and a last to create
|
1030
|
+
# the range.
|
1031
|
+
range = range.first..range.last
|
1032
|
+
end
|
1033
|
+
@range = range
|
1034
|
+
end
|
1035
|
+
|
1036
|
+
# Comparison for hash: structural comparison.
|
1037
|
+
def eql?(obj)
|
1038
|
+
# # General type comparison.
|
1039
|
+
# return false unless super(obj)
|
1040
|
+
# Specific comparison.
|
1041
|
+
return false unless obj.is_a?(TypeVector)
|
1042
|
+
return false unless @base.eql?(obj.base)
|
1043
|
+
return false unless @range.eql?(obj.range)
|
1044
|
+
return true
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
# Hash function.
|
1048
|
+
def hash
|
1049
|
+
return [super,@base,@range].hash
|
1050
|
+
end
|
1051
|
+
|
1052
|
+
# Gets the size of the type in number of base elements.
|
1053
|
+
def size
|
1054
|
+
return (@range.first.to_i - @range.last.to_i).abs + 1
|
1055
|
+
end
|
1056
|
+
|
1057
|
+
# Gets the bitwidth of the type, nil for undefined.
|
1058
|
+
#
|
1059
|
+
# NOTE: must be redefined for specific types.
|
1060
|
+
def width
|
1061
|
+
first = @range.first.to_i
|
1062
|
+
last = @range.last.to_i
|
1063
|
+
return @base.width * ((first-last).abs + 1)
|
1064
|
+
end
|
1065
|
+
|
1066
|
+
# Gets the type max value if any.
|
1067
|
+
def max
|
1068
|
+
if (self.signed?) then
|
1069
|
+
return (2**(self.width-1))-1
|
1070
|
+
else
|
1071
|
+
return (2**(self.width))-1
|
1072
|
+
end
|
1073
|
+
end
|
1074
|
+
|
1075
|
+
# Gets the type min value if any.
|
1076
|
+
# Default: not defined.
|
1077
|
+
def min
|
1078
|
+
if (self.signed?) then
|
1079
|
+
return -(2**(self.width-1))
|
1080
|
+
else
|
1081
|
+
return 0
|
1082
|
+
end
|
1083
|
+
end
|
1084
|
+
|
1085
|
+
# Get the direction of the type, little or big endian.
|
1086
|
+
def direction
|
1087
|
+
return @range.first < @range.last ? :big : :little
|
1088
|
+
end
|
1089
|
+
|
1090
|
+
# Gets the direction of the range.
|
1091
|
+
def dir
|
1092
|
+
return (@range.last - @range.first)
|
1093
|
+
end
|
1094
|
+
|
1095
|
+
# Tells if the type signed.
|
1096
|
+
def signed?
|
1097
|
+
return @base.signed?
|
1098
|
+
end
|
1099
|
+
|
1100
|
+
# Tells if the type is unsigned.
|
1101
|
+
def unsigned?
|
1102
|
+
return @base.unsigned?
|
1103
|
+
end
|
1104
|
+
|
1105
|
+
# Tells if the type is fixed point.
|
1106
|
+
def fixed?
|
1107
|
+
return @base.signed?
|
1108
|
+
end
|
1109
|
+
|
1110
|
+
# Tells if the type is floating point.
|
1111
|
+
def float?
|
1112
|
+
return @base.float?
|
1113
|
+
end
|
1114
|
+
|
1115
|
+
# Tell if +type+ is equivalent to current type.
|
1116
|
+
#
|
1117
|
+
# NOTE: type can be compatible while not being equivalent, please
|
1118
|
+
# refer to `hruby_types.rb` for type compatibility.
|
1119
|
+
def equivalent?(type)
|
1120
|
+
return (type.is_a?(TypeVector) and
|
1121
|
+
@range == type.range
|
1122
|
+
@base.equivalent?(type.base) )
|
1123
|
+
end
|
1124
|
+
|
1125
|
+
# Should not exists since it identifies types with multiple sub types.
|
1126
|
+
#
|
1127
|
+
# # Iterates over the sub types.
|
1128
|
+
# def each_type(&ruby_block)
|
1129
|
+
# # No ruby block? Return an enumerator.
|
1130
|
+
# return to_enum(:each_type) unless ruby_block
|
1131
|
+
# # A ruby block? Apply it on the base.
|
1132
|
+
# ruby_block.call(@base)
|
1133
|
+
# end
|
1134
|
+
|
1135
|
+
# Iterates over the types deeply if any.
|
1136
|
+
def each_type_deep(&ruby_block)
|
1137
|
+
# No ruby block? Return an enumerator.
|
1138
|
+
return to_enum(:each_type_deep) unless ruby_block
|
1139
|
+
# A ruby block? First apply it to current.
|
1140
|
+
ruby_block.call(self)
|
1141
|
+
# And recurse on the base.
|
1142
|
+
@base.each_type_deep(&ruby_block)
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
alias_method :each_deep, :each_type_deep
|
1146
|
+
end
|
1147
|
+
|
1148
|
+
|
1149
|
+
##
|
1150
|
+
# Describes a signed integer data type.
|
1151
|
+
class TypeSigned < TypeVector
|
1152
|
+
|
1153
|
+
# Creates a new vector type named +name+ from +base+ type and with
|
1154
|
+
# +range+.
|
1155
|
+
#
|
1156
|
+
# NOTE:
|
1157
|
+
# * The default range is 32-bit.
|
1158
|
+
def initialize(name,range = 31..0)
|
1159
|
+
# Initialize the type.
|
1160
|
+
super(name,Signed,range)
|
1161
|
+
end
|
1162
|
+
end
|
1163
|
+
|
1164
|
+
##
|
1165
|
+
# Describes an unsigned integer data type.
|
1166
|
+
class TypeUnsigned < TypeVector
|
1167
|
+
|
1168
|
+
# Creates a new vector type named +name+ from +base+ type and with
|
1169
|
+
# +range+.
|
1170
|
+
#
|
1171
|
+
# NOTE:
|
1172
|
+
# * The default range is 32-bit.
|
1173
|
+
def initialize(name,range = 31..0)
|
1174
|
+
# Initialize the type.
|
1175
|
+
super(name,Unsigned,range)
|
1176
|
+
end
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
##
|
1180
|
+
# Describes a float data type.
|
1181
|
+
class TypeFloat < TypeVector
|
1182
|
+
|
1183
|
+
# Creates a new vector type named +name+ from +base+ type and with
|
1184
|
+
# +range+.
|
1185
|
+
#
|
1186
|
+
# NOTE:
|
1187
|
+
# * The bits of negative range stands for the exponent
|
1188
|
+
# * The default range is for 64-bit IEEE 754 double precision standart
|
1189
|
+
def initialize(name,range = 52..-11)
|
1190
|
+
# Initialize the type.
|
1191
|
+
super(name,Float,range)
|
1192
|
+
end
|
1193
|
+
end
|
1194
|
+
|
1195
|
+
##
|
1196
|
+
# Describes a tuple type.
|
1197
|
+
class TypeTuple < Type
|
1198
|
+
# Creates a new tuple type named +name+ width +direction+ and whose
|
1199
|
+
# sub types are given by +content+.
|
1200
|
+
def initialize(name,direction,*content)
|
1201
|
+
# Initialize the type.
|
1202
|
+
super(name)
|
1203
|
+
|
1204
|
+
# Set the direction.
|
1205
|
+
@direction = direction.to_sym
|
1206
|
+
unless [:little, :big].include?(@direction)
|
1207
|
+
raise AnyError, "Invalid direction for a type: #{direction}"
|
1208
|
+
end
|
1209
|
+
|
1210
|
+
# Check and set the content.
|
1211
|
+
content.each do |sub|
|
1212
|
+
unless sub.is_a?(Type) then
|
1213
|
+
raise AnyError, "Invalid class for a type: #{sub.class}"
|
1214
|
+
end
|
1215
|
+
end
|
1216
|
+
@types = content
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
# Comparison for hash: structural comparison.
|
1220
|
+
def eql?(obj)
|
1221
|
+
# # General type comparison.
|
1222
|
+
# return false unless super(obj)
|
1223
|
+
return false unless obj.is_a?(TypeTuple)
|
1224
|
+
# Specific comparison.
|
1225
|
+
idx = 0
|
1226
|
+
obj.each_type do |type|
|
1227
|
+
return false unless @types[idx].eql?(type)
|
1228
|
+
idx += 1
|
1229
|
+
end
|
1230
|
+
return false unless idx == @types.size
|
1231
|
+
return true
|
1232
|
+
end
|
1233
|
+
|
1234
|
+
# Hash function.
|
1235
|
+
def hash
|
1236
|
+
return [super,@types].hash
|
1237
|
+
end
|
1238
|
+
|
1239
|
+
# Tells if the type has sub types.
|
1240
|
+
def types?
|
1241
|
+
return true
|
1242
|
+
end
|
1243
|
+
|
1244
|
+
# Gets an array containing all the syb types.
|
1245
|
+
def get_all_types
|
1246
|
+
return @types.clone
|
1247
|
+
end
|
1248
|
+
|
1249
|
+
# Gets a sub type by +index+.
|
1250
|
+
def get_type(index)
|
1251
|
+
return @types[index.to_i]
|
1252
|
+
end
|
1253
|
+
|
1254
|
+
# Adds a sub +type+.
|
1255
|
+
def add_type(type)
|
1256
|
+
unless type.is_a?(Type) then
|
1257
|
+
raise AnyError,
|
1258
|
+
"Invalid class for a type: #{type.class} (#{type})"
|
1259
|
+
end
|
1260
|
+
@types << type
|
1261
|
+
end
|
1262
|
+
|
1263
|
+
# Iterates over the sub name/type pair.
|
1264
|
+
#
|
1265
|
+
# Returns an enumerator if no ruby block is given.
|
1266
|
+
def each(&ruby_block)
|
1267
|
+
# No ruby block? Return an enumerator.
|
1268
|
+
return to_enum(:each) unless ruby_block
|
1269
|
+
# A ruby block? Apply it on each sub name/type pair.
|
1270
|
+
@types.each(&ruby_block)
|
1271
|
+
end
|
1272
|
+
|
1273
|
+
# Iterates over the sub types.
|
1274
|
+
#
|
1275
|
+
# Returns an enumerator if no ruby block is given.
|
1276
|
+
def each_type(&ruby_block)
|
1277
|
+
# No ruby block? Return an enumerator.
|
1278
|
+
return to_enum(:each_type) unless ruby_block
|
1279
|
+
# A ruby block? Apply it on each sub type.
|
1280
|
+
@types.each(&ruby_block)
|
1281
|
+
end
|
1282
|
+
|
1283
|
+
# Iterates over the types deeply if any.
|
1284
|
+
def each_type_deep(&ruby_block)
|
1285
|
+
# No ruby block? Return an enumerator.
|
1286
|
+
return to_enum(:each_type_deep) unless ruby_block
|
1287
|
+
# A ruby block? First apply it to current.
|
1288
|
+
ruby_block.call(self)
|
1289
|
+
# And recurse on the sub types.
|
1290
|
+
@types.each { |type| type.each_type_deep(&ruby_block) }
|
1291
|
+
end
|
1292
|
+
|
1293
|
+
alias_method :each_deep, :each_type_deep
|
1294
|
+
|
1295
|
+
# Tell if the tuple is regular, i.e., all its sub types are equivalent.
|
1296
|
+
#
|
1297
|
+
# NOTE: empty tuples are assumed not to be regular.
|
1298
|
+
def regular?
|
1299
|
+
return false if @types.empty?
|
1300
|
+
t0 = @types[0]
|
1301
|
+
@types[1..-1].each do |type|
|
1302
|
+
return false unless t0.equivalent?(type)
|
1303
|
+
end
|
1304
|
+
return true
|
1305
|
+
end
|
1306
|
+
|
1307
|
+
# Gets the bitwidth.
|
1308
|
+
def width
|
1309
|
+
return @types.reduce(0) { |sum,type| sum + type.width }
|
1310
|
+
end
|
1311
|
+
|
1312
|
+
# Get the direction of the type, little or big endian.
|
1313
|
+
def direction
|
1314
|
+
return @direction
|
1315
|
+
end
|
1316
|
+
|
1317
|
+
# Gets the range of the type.
|
1318
|
+
#
|
1319
|
+
# NOTE: only valid if the tuple is regular (i.e., all its sub types
|
1320
|
+
# are identical)
|
1321
|
+
def range
|
1322
|
+
if regular? then
|
1323
|
+
# Regular tuple, return its range as if it was an array.
|
1324
|
+
return 0..@types.size-1
|
1325
|
+
else
|
1326
|
+
raise AnyError, "No range for type #{self}"
|
1327
|
+
end
|
1328
|
+
end
|
1329
|
+
|
1330
|
+
# Tells if the type has a base.
|
1331
|
+
#
|
1332
|
+
# NOTE: only if the tuple is regular (i.e., all its sub types
|
1333
|
+
# are identical)
|
1334
|
+
def base?
|
1335
|
+
return regular?
|
1336
|
+
end
|
1337
|
+
|
1338
|
+
# Gets the base type.
|
1339
|
+
#
|
1340
|
+
# NOTE: only valid if the tuple is regular (i.e., all its sub types
|
1341
|
+
# are identical)
|
1342
|
+
def base
|
1343
|
+
if regular? then
|
1344
|
+
# Regular tuple, return the type of its first element.
|
1345
|
+
return @types[0]
|
1346
|
+
else
|
1347
|
+
raise AnyError, "No base type for type #{self}"
|
1348
|
+
end
|
1349
|
+
end
|
1350
|
+
|
1351
|
+
# Tell if +type+ is equivalent to current type.
|
1352
|
+
#
|
1353
|
+
# NOTE: type can be compatible while not being equivalent, please
|
1354
|
+
# refer to `hruby_types.rb` for type compatibility.
|
1355
|
+
def equivalent?(type)
|
1356
|
+
return (type.is_a?(TypeTuple) and
|
1357
|
+
!@types.zip(type.types).index {|t0,t1| !t0.equivalent?(t1) })
|
1358
|
+
end
|
1359
|
+
end
|
1360
|
+
|
1361
|
+
##
|
1362
|
+
# Describes a struct type.
|
1363
|
+
class TypeStruct < Type
|
1364
|
+
attr_reader :direction
|
1365
|
+
|
1366
|
+
# Creates a new structure type named +name+ with direction +dir+ and
|
1367
|
+
# whose hierachy is given by +content+.
|
1368
|
+
def initialize(name,dir,content)
|
1369
|
+
# Initialize the type.
|
1370
|
+
super(name)
|
1371
|
+
|
1372
|
+
# Set the direction.
|
1373
|
+
@direction = dir.to_sym
|
1374
|
+
unless [:little, :big].include?(@direction)
|
1375
|
+
raise AnyError, "Invalid direction for a type: #{dir}"
|
1376
|
+
end
|
1377
|
+
|
1378
|
+
# Check and set the content.
|
1379
|
+
content = Hash[content]
|
1380
|
+
@types = content.map do |k,v|
|
1381
|
+
unless v.is_a?(Type) then
|
1382
|
+
raise AnyError, "Invalid class for a type: #{v.class}"
|
1383
|
+
end
|
1384
|
+
[ k.to_sym, v ]
|
1385
|
+
end.to_h
|
1386
|
+
end
|
1387
|
+
|
1388
|
+
# Comparison for hash: structural comparison.
|
1389
|
+
def eql?(obj)
|
1390
|
+
# General type comparison.
|
1391
|
+
# return false unless super(obj)
|
1392
|
+
return false unless obj.is_a?(TypeStruct)
|
1393
|
+
# Specific comparison.
|
1394
|
+
idx = 0
|
1395
|
+
obj.each_key do |name|
|
1396
|
+
return false unless @types[name].eql?(obj.get_type(name))
|
1397
|
+
idx += 1
|
1398
|
+
end
|
1399
|
+
return false unless idx == @types.size
|
1400
|
+
return true
|
1401
|
+
end
|
1402
|
+
|
1403
|
+
# Hash function.
|
1404
|
+
def hash
|
1405
|
+
return [super,@types].hash
|
1406
|
+
end
|
1407
|
+
|
1408
|
+
# Tells if the type has named sub types.
|
1409
|
+
def struct?
|
1410
|
+
return true
|
1411
|
+
end
|
1412
|
+
|
1413
|
+
# Tells if the type has sub types.
|
1414
|
+
def types?
|
1415
|
+
return true
|
1416
|
+
end
|
1417
|
+
|
1418
|
+
# Gets an array containing all the syb types.
|
1419
|
+
def get_all_types
|
1420
|
+
return @types.values
|
1421
|
+
end
|
1422
|
+
|
1423
|
+
# Gets a sub type by +name+.
|
1424
|
+
# NOTE: +name+ can also be an index.
|
1425
|
+
def get_type(name)
|
1426
|
+
if name.respond_to?(:to_sym) then
|
1427
|
+
return @types[name.to_sym]
|
1428
|
+
else
|
1429
|
+
return @types.values[name.to_i]
|
1430
|
+
end
|
1431
|
+
end
|
1432
|
+
|
1433
|
+
# Iterates over the sub name/type pair.
|
1434
|
+
#
|
1435
|
+
# Returns an enumerator if no ruby block is given.
|
1436
|
+
def each(&ruby_block)
|
1437
|
+
# No ruby block? Return an enumerator.
|
1438
|
+
return to_enum(:each) unless ruby_block
|
1439
|
+
# A ruby block? Apply it on each sub name/type pair.
|
1440
|
+
@types.each(&ruby_block)
|
1441
|
+
end
|
1442
|
+
|
1443
|
+
# Iterates over the sub types.
|
1444
|
+
#
|
1445
|
+
# Returns an enumerator if no ruby block is given.
|
1446
|
+
def each_type(&ruby_block)
|
1447
|
+
# No ruby block? Return an enumerator.
|
1448
|
+
return to_enum(:each_type) unless ruby_block
|
1449
|
+
# A ruby block? Apply it on each sub type.
|
1450
|
+
@types.each_value(&ruby_block)
|
1451
|
+
end
|
1452
|
+
|
1453
|
+
# Iterates over the keys.
|
1454
|
+
#
|
1455
|
+
# Returns an enumerator if no ruby block is given.
|
1456
|
+
def each_key(&ruby_block)
|
1457
|
+
# No ruby block? Return an enumerator.
|
1458
|
+
return to_enum(:each_key) unless ruby_block
|
1459
|
+
# A ruby block? Apply it on each key.
|
1460
|
+
@types.each_key(&ruby_block)
|
1461
|
+
end
|
1462
|
+
|
1463
|
+
# Iterates over the sub type names.
|
1464
|
+
#
|
1465
|
+
# Returns an enumerator if no ruby block is given.
|
1466
|
+
def each_name(&ruby_block)
|
1467
|
+
# No ruby block? Return an enumerator.
|
1468
|
+
return to_enum(:each_name) unless ruby_block
|
1469
|
+
# A ruby block? Apply it on each name.
|
1470
|
+
@types.each_key(&ruby_block)
|
1471
|
+
end
|
1472
|
+
|
1473
|
+
# Iterates over the types deeply if any.
|
1474
|
+
def each_type_deep(&ruby_block)
|
1475
|
+
# No ruby block? Return an enumerator.
|
1476
|
+
return to_enum(:each_type_deep) unless ruby_block
|
1477
|
+
# A ruby block? First apply it to current.
|
1478
|
+
ruby_block.call(self)
|
1479
|
+
# And recurse on the sub types.
|
1480
|
+
@types.each_value { |type| type.each_type_deep(&ruby_block) }
|
1481
|
+
end
|
1482
|
+
|
1483
|
+
alias_method :each_deep, :each_type_deep
|
1484
|
+
|
1485
|
+
# Gets the bitwidth of the type, nil for undefined.
|
1486
|
+
#
|
1487
|
+
# NOTE: must be redefined for specific types.
|
1488
|
+
def width
|
1489
|
+
if @types.is_a?(Array) then
|
1490
|
+
return @types.reduce(0) {|sum,type| sum + type.width }
|
1491
|
+
else
|
1492
|
+
return @types.each_value.reduce(0) {|sum,type| sum + type.width }
|
1493
|
+
end
|
1494
|
+
end
|
1495
|
+
|
1496
|
+
# Tell if +type+ is equivalent to current type.
|
1497
|
+
#
|
1498
|
+
# NOTE: type can be compatible while not being equivalent, please
|
1499
|
+
# refer to `hruby_types.rb` for type compatibility.
|
1500
|
+
def equivalent?(type)
|
1501
|
+
return (type.is_a?(TypeStruct) and
|
1502
|
+
!@types.to_a.zip(type.types.to_a).index do |t0,t1|
|
1503
|
+
t0[0] != t1[0] or !t0[1].equivalent?(t1[1])
|
1504
|
+
end)
|
1505
|
+
end
|
1506
|
+
end
|
1507
|
+
|
1508
|
+
# The type constructors.
|
1509
|
+
|
1510
|
+
# Creates an unnamed structure type from a +content+.
|
1511
|
+
def struct(content)
|
1512
|
+
return TypeStruct.new(:"",:little,content)
|
1513
|
+
end
|
1514
|
+
|
1515
|
+
# Methods for declaring types
|
1516
|
+
|
1517
|
+
# Declares a high-level generic type named +name+, and using +ruby_block+
|
1518
|
+
# for construction.
|
1519
|
+
def typedef(name, &ruby_block)
|
1520
|
+
# Ensure there is a block.
|
1521
|
+
ruby_block = proc {} unless block_given?
|
1522
|
+
type = TypeGen.new(name,&ruby_block)
|
1523
|
+
define_singleton_method(name.to_sym) do |*args|
|
1524
|
+
if (args.size < ruby_block.arity) then
|
1525
|
+
# Not enough arguments get generic type as is.
|
1526
|
+
type
|
1527
|
+
else
|
1528
|
+
# There are arguments, specialize the type.
|
1529
|
+
gtype = type.generate(*args)
|
1530
|
+
# And add it as a local type of the system.
|
1531
|
+
RubyHDL::High.top_sblock.add_type(gtype)
|
1532
|
+
gtype
|
1533
|
+
end
|
1534
|
+
end
|
1535
|
+
end
|
1536
|
+
|
1537
|
+
|
1538
|
+
|
1539
|
+
## Describes the software implementation of an expression.
|
1540
|
+
class Expression
|
1541
|
+
using RubyHDL::High
|
1542
|
+
|
1543
|
+
attr_reader :type
|
1544
|
+
# Create a new expression with +type+ data type.
|
1545
|
+
def initialize(type)
|
1546
|
+
@type = type.to_type
|
1547
|
+
end
|
1548
|
+
|
1549
|
+
# Converts to an expression.
|
1550
|
+
def to_expr
|
1551
|
+
self
|
1552
|
+
end
|
1553
|
+
|
1554
|
+
alias_method :to_ref, :to_expr
|
1555
|
+
|
1556
|
+
# Compute the expression (convert it to a value).
|
1557
|
+
def to_value
|
1558
|
+
raise "to_value not defined here."
|
1559
|
+
end
|
1560
|
+
|
1561
|
+
# Convert to ruby code.
|
1562
|
+
def to_ruby
|
1563
|
+
raise "to_ruby not defined for class: #{self.class}."
|
1564
|
+
end
|
1565
|
+
|
1566
|
+
# Convert to ruby code for left value.
|
1567
|
+
# By default: the same as to_ruby
|
1568
|
+
alias_method :to_ruby_left, :to_ruby
|
1569
|
+
|
1570
|
+
# The implementation of the expressions generation.
|
1571
|
+
|
1572
|
+
# The unary operations generation.
|
1573
|
+
[:"-@",:"+@",:"~", :abs,
|
1574
|
+
:boolean, :bit, :signed, :unsigned].each do |operator|
|
1575
|
+
self.define_method(operator) do
|
1576
|
+
return Unary.new(self.type,operator,self.to_expr)
|
1577
|
+
end
|
1578
|
+
end
|
1579
|
+
|
1580
|
+
# The binary operations generation.
|
1581
|
+
[:"+",:"-",:"*",:"/",:"%",:"**",
|
1582
|
+
:"&",:"|",:"^",
|
1583
|
+
:"<<",:">>",# :ls,:rs,:lr,:rr, # ls, rs lr and rr are treated separately
|
1584
|
+
:"==",:"!=",:"<",:">",:">="].each do |operator|
|
1585
|
+
# :"<=" is processed appart for transmit.
|
1586
|
+
self.define_method(operator) do |right|
|
1587
|
+
return Binary.new(self.type,operator,self.to_expr,right.to_expr)
|
1588
|
+
end
|
1589
|
+
end
|
1590
|
+
|
1591
|
+
# The <= operator which can be either a transmit or a comparison.
|
1592
|
+
# By default set to transmit, and converted to comparison if
|
1593
|
+
# child of operator or condition of sif/swhile statements.
|
1594
|
+
def <=(right)
|
1595
|
+
return Transmit.new(self.to_expr,right.to_expr)
|
1596
|
+
end
|
1597
|
+
|
1598
|
+
# TO DO?
|
1599
|
+
# # The <=> operator is also supported but is transformed into a sub
|
1600
|
+
# # with a signed result.
|
1601
|
+
# def <=>(right)
|
1602
|
+
# return (self.as(self.type.base[self.type.width+1])-right).to_signed
|
1603
|
+
# end
|
1604
|
+
|
1605
|
+
# Creates an access to elements of range +rng+ of the signal,
|
1606
|
+
# and set the type of elements as +typ+ if given.
|
1607
|
+
#
|
1608
|
+
# NOTE: +rng+ can be a single expression in which case it is an index.
|
1609
|
+
def [](typ,rng=nil)
|
1610
|
+
# Treat the number of arguments
|
1611
|
+
rng, typ = typ, nil unless rng
|
1612
|
+
# Process the range.
|
1613
|
+
if rng.is_a?(::Range) then
|
1614
|
+
first = rng.first
|
1615
|
+
if (first.is_a?(::Integer)) then
|
1616
|
+
first = self.type.size+first if first < 0
|
1617
|
+
end
|
1618
|
+
last = rng.last
|
1619
|
+
if (last.is_a?(::Integer)) then
|
1620
|
+
last = self.type.size+last if last < 0
|
1621
|
+
end
|
1622
|
+
rng = first..last
|
1623
|
+
end
|
1624
|
+
if rng.is_a?(::Integer) && rng < 0 then
|
1625
|
+
rng = self.type.size+rng
|
1626
|
+
end
|
1627
|
+
if rng.respond_to?(:to_expr) then
|
1628
|
+
# Number range: convert it to an expression.
|
1629
|
+
rng = rng.to_expr
|
1630
|
+
end
|
1631
|
+
if rng.is_a?(Expression) then
|
1632
|
+
# Index case
|
1633
|
+
if typ then
|
1634
|
+
return RefIndex.new(typ,self.to_expr,rng)
|
1635
|
+
else
|
1636
|
+
return RefIndex.new(self.type.base,self.to_expr,rng)
|
1637
|
+
end
|
1638
|
+
else
|
1639
|
+
# Range case, ensure it is made among expression.
|
1640
|
+
first = rng.first.to_expr
|
1641
|
+
last = rng.last.to_expr
|
1642
|
+
# And create the reference.
|
1643
|
+
if typ then
|
1644
|
+
return RefRange.new(typ,
|
1645
|
+
self.to_expr,first..last)
|
1646
|
+
else
|
1647
|
+
return RefRange.new(self.type.slice(first..last),
|
1648
|
+
self.to_expr,first..last)
|
1649
|
+
end
|
1650
|
+
end
|
1651
|
+
end
|
1652
|
+
|
1653
|
+
# Converts to a select operator using current expression as
|
1654
|
+
# condition for one of the +choices+.
|
1655
|
+
#
|
1656
|
+
# NOTE: +choices+ can either be a list of arguments or an array.
|
1657
|
+
# If +choices+ has only two entries
|
1658
|
+
# (and it is not a hash), +value+ will be converted to a boolean.
|
1659
|
+
def mux(*choices)
|
1660
|
+
# Process the choices.
|
1661
|
+
choices = choices.flatten(1) if choices.size == 1
|
1662
|
+
choices.map! { |choice| choice.to_expr }
|
1663
|
+
# Generate the select expression.
|
1664
|
+
return Select.new(choices[0].type,self.to_expr,*choices)
|
1665
|
+
end
|
1666
|
+
|
1667
|
+
# The implementation of the interators.
|
1668
|
+
|
1669
|
+
# HW iteration on each element.
|
1670
|
+
def seach(&ruby_block)
|
1671
|
+
RubyHDL::High.top_sblock <<
|
1672
|
+
Siter.new(RubyHDL::High.top_sblock.sequencer,self,"each",&ruby_block)
|
1673
|
+
end
|
1674
|
+
|
1675
|
+
# HW times iteration.
|
1676
|
+
def stimes(&ruby_block)
|
1677
|
+
RubyHDL::High.top_sblock <<
|
1678
|
+
Siter.new(RubyHDL::High.top_sblock.sequencer,self,"times",&ruby_block)
|
1679
|
+
end
|
1680
|
+
|
1681
|
+
# HW upto iteration.
|
1682
|
+
def supto(val,&ruby_block)
|
1683
|
+
RubyHDL::High.top_sblock <<
|
1684
|
+
Siter.new(RubyHDL::High.top_sblock.sequencer,self,"upto",&ruby_block)
|
1685
|
+
end
|
1686
|
+
|
1687
|
+
# HW downto iteration.
|
1688
|
+
def sdownto(val,&ruby_block)
|
1689
|
+
RubyHDL::High.top_sblock <<
|
1690
|
+
Siter.new(RubyHDL::High.top_sblock.sequencer,self,"downto",&ruby_block)
|
1691
|
+
end
|
1692
|
+
end
|
1693
|
+
|
1694
|
+
|
1695
|
+
##
|
1696
|
+
# Describes the software implementation of a value.
|
1697
|
+
class Value < Expression
|
1698
|
+
|
1699
|
+
attr_reader :content
|
1700
|
+
|
1701
|
+
# Create a new value with +type+ data type and content +content+.
|
1702
|
+
def initialize(type,content)
|
1703
|
+
super(type)
|
1704
|
+
@content = content
|
1705
|
+
end
|
1706
|
+
|
1707
|
+
# Compute the expression (convert it to a value).
|
1708
|
+
def to_value
|
1709
|
+
return self
|
1710
|
+
end
|
1711
|
+
|
1712
|
+
# Convert to ruby code.
|
1713
|
+
def to_ruby
|
1714
|
+
return @content.to_s
|
1715
|
+
end
|
1716
|
+
end
|
1717
|
+
|
1718
|
+
|
1719
|
+
# Describes the software implementation of an unary operation.
|
1720
|
+
class Unary < Expression
|
1721
|
+
# Create a new unary operation with +type+ data type,
|
1722
|
+
# operator +operator+ and operand +child+
|
1723
|
+
def initialize(type,operator,child)
|
1724
|
+
super(type)
|
1725
|
+
@operator = operator.to_sym
|
1726
|
+
@child = child.to_expr
|
1727
|
+
end
|
1728
|
+
|
1729
|
+
# Convert to ruby code.
|
1730
|
+
def to_ruby
|
1731
|
+
return RUBY_OPERATOR[@operator] % @child.to_ruby
|
1732
|
+
end
|
1733
|
+
end
|
1734
|
+
|
1735
|
+
# Describes the software implementation of an binary operation.
|
1736
|
+
class Binary < Expression
|
1737
|
+
# Create a new binary operation with +type+ data type,
|
1738
|
+
# operator +operator+ and operands +left+ and +right+.
|
1739
|
+
def initialize(type,operator,left,right)
|
1740
|
+
super(type)
|
1741
|
+
@operator = operator.to_sym
|
1742
|
+
@left = left.to_expr
|
1743
|
+
@right = right.to_expr
|
1744
|
+
end
|
1745
|
+
|
1746
|
+
# Convert to ruby code.
|
1747
|
+
def to_ruby
|
1748
|
+
return RUBY_OPERATOR[@operator] % [ @left.to_ruby, @right.to_ruby ]
|
1749
|
+
end
|
1750
|
+
end
|
1751
|
+
|
1752
|
+
# Describes the software implementation of an select operation.
|
1753
|
+
class Select < Expression
|
1754
|
+
# Create a new select operation with +type+ data type,
|
1755
|
+
# selection operand +sel+ and possible choices +choices+.
|
1756
|
+
def initialize(type,operator,sel,*choices)
|
1757
|
+
super(type)
|
1758
|
+
@sel = sel.to_expr
|
1759
|
+
@choices = choices.map(&:to_expr)
|
1760
|
+
end
|
1761
|
+
|
1762
|
+
# Convert to ruby code.
|
1763
|
+
def to_ruby
|
1764
|
+
return "case(#{@sel.to_}) ; " +
|
1765
|
+
@choices.map.with_index do |choice,i|
|
1766
|
+
"when #{i} ; #{choice.to_ruby} ; "
|
1767
|
+
end.join + "end"
|
1768
|
+
end
|
1769
|
+
end
|
1770
|
+
|
1771
|
+
# Describes a SW implementation of a reference.
|
1772
|
+
class Ref < Expression
|
1773
|
+
def to_ref
|
1774
|
+
return self
|
1775
|
+
end
|
1776
|
+
|
1777
|
+
# Get the final base: by default self.
|
1778
|
+
def final_base
|
1779
|
+
return self
|
1780
|
+
end
|
1781
|
+
|
1782
|
+
# # Get the final first index of the range, by default: 0
|
1783
|
+
# def final_first
|
1784
|
+
# return 0
|
1785
|
+
# end
|
1786
|
+
|
1787
|
+
# # Get the final range, by default: @type.width-1..0
|
1788
|
+
# def final_range
|
1789
|
+
# (@type.width-1)..0
|
1790
|
+
# end
|
1791
|
+
end
|
1792
|
+
|
1793
|
+
# Describes a SW implementation of a reference by name.
|
1794
|
+
class RefName < Ref
|
1795
|
+
# Create a new named reference with +type+ data type and +name+ name.
|
1796
|
+
def initialize(type,name)
|
1797
|
+
super(type)
|
1798
|
+
@name = name.to_sym
|
1799
|
+
end
|
1800
|
+
|
1801
|
+
# Convert to ruby code.
|
1802
|
+
def to_ruby
|
1803
|
+
return @name.to_s
|
1804
|
+
end
|
1805
|
+
end
|
1806
|
+
|
1807
|
+
# Describes a SW implementation of an index reference.
|
1808
|
+
class RefIndex < Ref
|
1809
|
+
attr_reader :base
|
1810
|
+
|
1811
|
+
# Create a new index reference with +type+ data type +base+ base
|
1812
|
+
# reference and +idx+ index.
|
1813
|
+
def initialize(type,base,idx)
|
1814
|
+
super(type)
|
1815
|
+
@base = base.to_expr
|
1816
|
+
@idx = idx.to_expr
|
1817
|
+
end
|
1818
|
+
|
1819
|
+
# Get the final base object of the binary if it is an [] operator.
|
1820
|
+
def final_base
|
1821
|
+
if @base.is_a?(Ref) then
|
1822
|
+
return @base.final_base
|
1823
|
+
else
|
1824
|
+
return @base
|
1825
|
+
end
|
1826
|
+
end
|
1827
|
+
|
1828
|
+
# # Get the final first index.
|
1829
|
+
# def final_first
|
1830
|
+
# btyp = @base.type.base
|
1831
|
+
# idx = @base.type.dir <= 0 ? @idx : -@idx
|
1832
|
+
# # Compute the current access range.
|
1833
|
+
# first = idx*btyp.width
|
1834
|
+
# # Position it if there are upper ref access.
|
1835
|
+
# if @base.is_a?(Ref) then
|
1836
|
+
# first += @base.final_first
|
1837
|
+
# end
|
1838
|
+
# return first
|
1839
|
+
# end
|
1840
|
+
|
1841
|
+
# # Get the final access range.
|
1842
|
+
# def final_range
|
1843
|
+
# btyp = @base.type.base
|
1844
|
+
# idx = @base.type.dir <= 0 ? @idx : -@idx
|
1845
|
+
# # Compute the current access range.
|
1846
|
+
# rng = ((idx+1)*btyp.width-1)..(idx*btyp.width)
|
1847
|
+
# # Position it if there are upper ref access.
|
1848
|
+
# if @base.is_a?(Ref) then
|
1849
|
+
# rng.first += @base.final_first
|
1850
|
+
# rng.last += @base.final_first
|
1851
|
+
# end
|
1852
|
+
# return rng
|
1853
|
+
# end
|
1854
|
+
|
1855
|
+
# Get the access range.
|
1856
|
+
def range
|
1857
|
+
return @idx..@idx
|
1858
|
+
end
|
1859
|
+
|
1860
|
+
# Convert to ruby code.
|
1861
|
+
def to_ruby
|
1862
|
+
return "#{@base.to_ruby}[#{@idx.to_ruby}]"
|
1863
|
+
end
|
1864
|
+
end
|
1865
|
+
|
1866
|
+
# Describes a SW implementation of an range reference.
|
1867
|
+
class RefRange < Ref
|
1868
|
+
attr_reader :base
|
1869
|
+
|
1870
|
+
# Create a new index reference with +type+ data type +base+ base
|
1871
|
+
# reference and +rng+ range.
|
1872
|
+
def initialize(type,base,rng)
|
1873
|
+
super(type)
|
1874
|
+
@base = base.to_ref
|
1875
|
+
@rng = (rng.first.to_expr)..(rng.last.to_expr)
|
1876
|
+
end
|
1877
|
+
|
1878
|
+
# Get the access range.
|
1879
|
+
def range
|
1880
|
+
return @rng.first..@rng.last
|
1881
|
+
end
|
1882
|
+
|
1883
|
+
# Get the final base object of the binary if it is an [] operator.
|
1884
|
+
def final_base
|
1885
|
+
if @base.is_a?(Ref) then
|
1886
|
+
return @base.final_base
|
1887
|
+
else
|
1888
|
+
return @base
|
1889
|
+
end
|
1890
|
+
end
|
1891
|
+
|
1892
|
+
# # Get the final first index.
|
1893
|
+
# def final_first
|
1894
|
+
# btyp = @base.type.base
|
1895
|
+
# idx = @base.type.dir <= 0 ? @rng.first : @rng.last
|
1896
|
+
# # Compute the current access range.
|
1897
|
+
# first = idx*btyp.width
|
1898
|
+
# # Position it if there are upper ref access.
|
1899
|
+
# if @base.is_a?(Ref) then
|
1900
|
+
# first += @base.final_first
|
1901
|
+
# end
|
1902
|
+
# return first
|
1903
|
+
# end
|
1904
|
+
|
1905
|
+
# # Get the final access range.
|
1906
|
+
# def final_range
|
1907
|
+
# btyp = @base.type.base
|
1908
|
+
# rng = @base.type.dir <= 0 ? @rng : @rng.last..@rng.first
|
1909
|
+
# # Compute the current access range.
|
1910
|
+
# rng = ((rng.first+1)*btyp.width-1)..(rng.last*btyp.width)
|
1911
|
+
# # Position it if there are upper ref access.
|
1912
|
+
# if @base.is_a?(Ref) then
|
1913
|
+
# rng.first += @base.final_first
|
1914
|
+
# rng.last += @base.final_first
|
1915
|
+
# end
|
1916
|
+
# return rng
|
1917
|
+
# end
|
1918
|
+
|
1919
|
+
# Convert to ruby code.
|
1920
|
+
def to_ruby
|
1921
|
+
return "#{@base.to_ruby}[#{@rng.first.to_ruby}..#{@rng.last.to_ruby}]"
|
1922
|
+
end
|
1923
|
+
end
|
1924
|
+
|
1925
|
+
|
1926
|
+
|
1927
|
+
# Describes a SW implementation of a transmit statement.
|
1928
|
+
class Transmit
|
1929
|
+
using RubyHDL::High
|
1930
|
+
|
1931
|
+
attr_reader :left, :right
|
1932
|
+
|
1933
|
+
# Create a new transmit statement with left value +left+ and
|
1934
|
+
# right value +right+.
|
1935
|
+
def initialize(left,right)
|
1936
|
+
@left = left.to_expr
|
1937
|
+
@right = right.to_expr
|
1938
|
+
# Add the transmit to the top SW block.
|
1939
|
+
# (It will be removed after if it was actually a comparison).
|
1940
|
+
RubyHDL::High.top_sblock << self
|
1941
|
+
end
|
1942
|
+
|
1943
|
+
# Convert to expression: transforms the transmit to a comparison.
|
1944
|
+
def to_expr
|
1945
|
+
# Remove the transmit from the top SW block.
|
1946
|
+
RubyHDL::High.top_sblock.delete(self)
|
1947
|
+
# And convert it to a comparison.
|
1948
|
+
return Binary.new(@left.type,@left,@right)
|
1949
|
+
end
|
1950
|
+
|
1951
|
+
# Convert to ruby code.
|
1952
|
+
def to_ruby
|
1953
|
+
if (@left.is_a?(RefIndex) or @left.is_a?(RefRange)) then
|
1954
|
+
if @left.base.type.base.is_a?(TypeVector) then
|
1955
|
+
# Assign inside array.
|
1956
|
+
base = @left.final_base.to_ruby
|
1957
|
+
return "#{base} ||= []; #{@left.to_ruby} = #{@right.to_ruby}"
|
1958
|
+
else
|
1959
|
+
# # Compute the final access range.
|
1960
|
+
# rng = @left.final_range
|
1961
|
+
# Get the access range.
|
1962
|
+
rng = @left.range
|
1963
|
+
# Compute the writing and clearing masks
|
1964
|
+
smask = (1.to_value<<(rng.first+1-rng.last))-1
|
1965
|
+
cmask = ~(smask << rng.last)
|
1966
|
+
# Get the final base.
|
1967
|
+
base = left.final_base.to_ruby
|
1968
|
+
# Generate the ruby code.
|
1969
|
+
return "#{base} &= #{cmask.to_ruby}; " +
|
1970
|
+
"#{base} |= (((#{@right.to_ruby} & #{smask.to_ruby}) << (#{rng.last.to_ruby})))"
|
1971
|
+
end
|
1972
|
+
else
|
1973
|
+
return "#{@left.to_ruby} = #{@right.to_ruby}"
|
1974
|
+
end
|
1975
|
+
end
|
1976
|
+
end
|
1977
|
+
|
1978
|
+
# Describes a SW implementation of a if statement.
|
1979
|
+
class Sif
|
1980
|
+
# Create a new if statement in sequencer +sequencer+
|
1981
|
+
# with +cond+ condition and +ruby_block+
|
1982
|
+
# for generating the block that is taken if the condition is met.
|
1983
|
+
def initialize(sequencer,cond, &ruby_block)
|
1984
|
+
@sequencer = sequencer
|
1985
|
+
@condition = cond.to_expr
|
1986
|
+
@yes_blk = Sblock.new(@sequencer,&ruby_block)
|
1987
|
+
@elsifs = []
|
1988
|
+
@else_blk = nil
|
1989
|
+
end
|
1990
|
+
|
1991
|
+
# Add a selsif case.
|
1992
|
+
def selsif(cond,&ruby_block)
|
1993
|
+
@elsifs << [cond,Sblock.new(@sequencer,&ruby_block)]
|
1994
|
+
end
|
1995
|
+
|
1996
|
+
# Sets the else block.
|
1997
|
+
def selse(&ruby_block)
|
1998
|
+
@else_blk = Sblock.new(@sequencer,&ruby_block)
|
1999
|
+
end
|
2000
|
+
|
2001
|
+
# Convert to ruby code.
|
2002
|
+
def to_ruby
|
2003
|
+
res = @sequencer.clk_up + "\nif(#{@cond.to_ruby})\n#{@yes.to_ruby}\n"
|
2004
|
+
@elsifs.each do |(cond,blk)|
|
2005
|
+
res << "elsif(#{cond.to_ruby})\n#{blk.to_ruby}\n"
|
2006
|
+
end
|
2007
|
+
if @else_blk then
|
2008
|
+
res << "else\n#{@else_blk.to_ruby}\n"
|
2009
|
+
end
|
2010
|
+
return res + @sequencer.clk_up
|
2011
|
+
end
|
2012
|
+
end
|
2013
|
+
|
2014
|
+
# Describes a SW implementation of a loop statement.
|
2015
|
+
class Sloop
|
2016
|
+
# Create a new infinite loop statement in sequencer +sequencer+
|
2017
|
+
# with +ruby_block+ for generating the block that is taken.
|
2018
|
+
def initialize(sequencer, &ruby_block)
|
2019
|
+
@sequencer = sequencer
|
2020
|
+
@blk = Sblock.new(sequencer,&ruby_block)
|
2021
|
+
end
|
2022
|
+
|
2023
|
+
# Convert to ruby code.
|
2024
|
+
def to_ruby
|
2025
|
+
return "loop do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend\n"
|
2026
|
+
end
|
2027
|
+
end
|
2028
|
+
|
2029
|
+
# Describes a SW implementation of a while statement.
|
2030
|
+
class Swhile
|
2031
|
+
# Create a new while statement in sequencer +sequencer+
|
2032
|
+
# with +cond+ condition and +ruby_block+
|
2033
|
+
# for generating the block that is taken while the condition is met.
|
2034
|
+
def initialize(sequencer,cond, &ruby_block)
|
2035
|
+
@sequencer = sequencer
|
2036
|
+
@condition = cond.to_expr
|
2037
|
+
@yes_blk = Sblock.new(sequencer,&ruby_block)
|
2038
|
+
end
|
2039
|
+
|
2040
|
+
# Convert to ruby code.
|
2041
|
+
def to_ruby
|
2042
|
+
return @sequencer.clk_up +
|
2043
|
+
"\nwhile(#{@condition.to_ruby}) do\n#{@yes_blk.to_ruby}\n#{@sequencer.clk_up}\nend\n"
|
2044
|
+
end
|
2045
|
+
end
|
2046
|
+
|
2047
|
+
# Describes a SW implementation of a step statement.
|
2048
|
+
class Step
|
2049
|
+
# Create a new step statement in sequencer +sequencer+.
|
2050
|
+
def initialize(sequencer)
|
2051
|
+
@sequencer = sequencer
|
2052
|
+
end
|
2053
|
+
|
2054
|
+
# Convert to ruby code.
|
2055
|
+
def to_ruby
|
2056
|
+
return @sequencer.clk_up
|
2057
|
+
end
|
2058
|
+
end
|
2059
|
+
|
2060
|
+
# Describes a SW implementation of a break statement.
|
2061
|
+
class Sbreak
|
2062
|
+
# Create a new break statement in sequencer +sequencer+.
|
2063
|
+
def initialize(sequencer)
|
2064
|
+
@sequencer = sequencer
|
2065
|
+
end
|
2066
|
+
|
2067
|
+
# Convert to ruby code.
|
2068
|
+
def to_ruby
|
2069
|
+
return @sequencer.clk_up + "\nbreak"
|
2070
|
+
end
|
2071
|
+
end
|
2072
|
+
|
2073
|
+
# Describes a SW implementation of a continue statement.
|
2074
|
+
class Scontinue
|
2075
|
+
# Create a new break statement in sequencer +sequencer+.
|
2076
|
+
def initialize
|
2077
|
+
@sequencer = sequencer
|
2078
|
+
end
|
2079
|
+
|
2080
|
+
# Convert to ruby code.
|
2081
|
+
def to_ruby
|
2082
|
+
return @sequencer.clk_up + "\ncontinue"
|
2083
|
+
end
|
2084
|
+
end
|
2085
|
+
|
2086
|
+
# Describes a SW implementation of a terminate statement.
|
2087
|
+
class Sterminate
|
2088
|
+
# Create a new break statement in sequencer +sequencer+.
|
2089
|
+
def initialize
|
2090
|
+
@sequencer = sequencer
|
2091
|
+
end
|
2092
|
+
|
2093
|
+
# Convert to ruby code.
|
2094
|
+
def to_ruby
|
2095
|
+
# Implemented as returning from a function since a sequencer
|
2096
|
+
# is implemented as one.
|
2097
|
+
return @sequencer.clk_up + "\nreturn"
|
2098
|
+
end
|
2099
|
+
end
|
2100
|
+
|
2101
|
+
# Describes a SW synchronization of a signal.
|
2102
|
+
class Sync
|
2103
|
+
def initialize
|
2104
|
+
end
|
2105
|
+
|
2106
|
+
# Convert to ruby code.
|
2107
|
+
def to_ruby
|
2108
|
+
return "Fiber.yield"
|
2109
|
+
end
|
2110
|
+
end
|
2111
|
+
|
2112
|
+
# Describes arbitrary code.
|
2113
|
+
class Ruby < Expression
|
2114
|
+
@@ruby_blocks = []
|
2115
|
+
|
2116
|
+
# Create a new ruby code block for +ruby_block+.
|
2117
|
+
def initialize(&ruby_block)
|
2118
|
+
# puts "ruby_block=#{ruby_block}"
|
2119
|
+
# Create the id for the block.
|
2120
|
+
@id = @@ruby_blocks.size
|
2121
|
+
# Adds the block.
|
2122
|
+
@@ruby_blocks << ruby_block
|
2123
|
+
end
|
2124
|
+
|
2125
|
+
# Convert to expression: does not change but remove from the
|
2126
|
+
# statement list.
|
2127
|
+
def to_expr
|
2128
|
+
# Remove the transmit from the top SW block.
|
2129
|
+
RubyHDL::High.top_sblock.delete(self)
|
2130
|
+
return self
|
2131
|
+
end
|
2132
|
+
|
2133
|
+
# Execute a ruby code block for +ruby_block+.
|
2134
|
+
def self.call(id)
|
2135
|
+
# puts "id=#{id}"
|
2136
|
+
@@ruby_blocks[id].call
|
2137
|
+
end
|
2138
|
+
|
2139
|
+
# Convert to ruby code.
|
2140
|
+
def to_ruby
|
2141
|
+
puts caller[0]
|
2142
|
+
return "RubyHDL::High::Ruby.call(#{@id})"
|
2143
|
+
end
|
2144
|
+
end
|
2145
|
+
|
2146
|
+
# Describes a SW implementation of an iterator statement.
|
2147
|
+
class Siter
|
2148
|
+
using RubyHDL::High
|
2149
|
+
|
2150
|
+
# Create a new iteration statement in sequencer +sequencer+
|
2151
|
+
# for chain of commands +commands+ to interate while
|
2152
|
+
# executing +ruby_block+.
|
2153
|
+
def initialize(sequencer,*commands, &ruby_block)
|
2154
|
+
@sequencer = sequencer
|
2155
|
+
puts "@sequencer=#{@sequencer}"
|
2156
|
+
@commands = commands
|
2157
|
+
@blk = Sblock.new(sequencer,&ruby_block)
|
2158
|
+
end
|
2159
|
+
|
2160
|
+
# Iterate on the commands.
|
2161
|
+
def each_command(&ruby_block)
|
2162
|
+
return to_enum(:each_command) unless ruby_block
|
2163
|
+
@commands.each(&ruby_block)
|
2164
|
+
end
|
2165
|
+
alias_method :each, :each_command
|
2166
|
+
|
2167
|
+
# Convert to ruby code.
|
2168
|
+
def to_ruby
|
2169
|
+
res = @sequencer.clk_up + "\n" +
|
2170
|
+
@commands.map { |command| command.to_ruby }.join(".")
|
2171
|
+
return res + " do\n#{@blk.to_ruby}\n#{@sequencer.clk_up}\nend"
|
2172
|
+
end
|
2173
|
+
|
2174
|
+
# Create an iterator for a given method +meth+.
|
2175
|
+
def make_iterator(meth,*args,&ruby_block)
|
2176
|
+
if ruby_block then
|
2177
|
+
blk = Sblock.new(@sequencer,&ruby_block)
|
2178
|
+
command = RubyHDL::High::Ruby.new do
|
2179
|
+
"#{meth}(#{args.map{|arg| arg.to_ruby}.join(",")}) { #{blk.to_ruby} }"
|
2180
|
+
end
|
2181
|
+
else
|
2182
|
+
command = RubyHDL::High::Ruby.new do
|
2183
|
+
"#{meth}(#{args.map{|arg| arg.to_ruby}.join(",")})"
|
2184
|
+
end
|
2185
|
+
end
|
2186
|
+
return Iter.new(@sequencer,*self.commands,command,&ruby_block)
|
2187
|
+
end
|
2188
|
+
|
2189
|
+
# The iterator methods.
|
2190
|
+
|
2191
|
+
# Iterator on each of the elements in range +rng+.
|
2192
|
+
# *NOTE*:
|
2193
|
+
# - Stop iteration when the end of the range is reached or when there
|
2194
|
+
# are no elements left
|
2195
|
+
# - This is not a method from Ruby but one specific for hardware where
|
2196
|
+
# creating a array is very expensive.
|
2197
|
+
def seach_range(rng,&ruby_block)
|
2198
|
+
return self.make_iterator("each_range",rng,&ruby_block)
|
2199
|
+
end
|
2200
|
+
|
2201
|
+
# Tell if all the elements respect a given criterion given either
|
2202
|
+
# as +arg+ or as block.
|
2203
|
+
def sall?(arg = nil,&ruby_block)
|
2204
|
+
return self.make_iterator("all?",arg,&ruby_block)
|
2205
|
+
end
|
2206
|
+
|
2207
|
+
# Tell if any of the elements respects a given criterion given either
|
2208
|
+
# as +arg+ or as block.
|
2209
|
+
def sany?(arg = nil,&ruby_block)
|
2210
|
+
return self.make_iterator("any?",arg,&ruby_block)
|
2211
|
+
end
|
2212
|
+
|
2213
|
+
# Returns an SEnumerator generated from current enumerable and +arg+
|
2214
|
+
def schain(arg)
|
2215
|
+
return self.make_iterator("chain",arg)
|
2216
|
+
end
|
2217
|
+
|
2218
|
+
# HW implementation of the Ruby chunk.
|
2219
|
+
# NOTE: to do, or may be not.
|
2220
|
+
def schunk(*args,&ruby_block)
|
2221
|
+
raise "schunk is not supported yet."
|
2222
|
+
end
|
2223
|
+
|
2224
|
+
# HW implementation of the Ruby chunk_while.
|
2225
|
+
# NOTE: to do, or may be not.
|
2226
|
+
def schunk_while(*args,&ruby_block)
|
2227
|
+
raise "schunk_while is not supported yet."
|
2228
|
+
end
|
2229
|
+
|
2230
|
+
# Returns a vector containing the execution result of the given block
|
2231
|
+
# on each element. If no block is given, return an SEnumerator.
|
2232
|
+
# NOTE: be carful that the resulting vector can become huge if there
|
2233
|
+
# are many element.
|
2234
|
+
def smap(&ruby_block)
|
2235
|
+
return self.make_iterator("map",&ruby_block)
|
2236
|
+
end
|
2237
|
+
|
2238
|
+
# HW implementation of the Ruby flat_map.
|
2239
|
+
# NOTE: actually due to the way HDLRuby handles vectors, should work
|
2240
|
+
# like smap
|
2241
|
+
def sflat_map(&ruby_block)
|
2242
|
+
return self.make_iterator("flat_map",&ruby_block)
|
2243
|
+
end
|
2244
|
+
|
2245
|
+
# HW implementation of the Ruby compact, but remove 0 values instead
|
2246
|
+
# on nil (since nil that does not have any meaning in HW).
|
2247
|
+
def scompact
|
2248
|
+
return self.make_iterator("compact",&ruby_block)
|
2249
|
+
end
|
2250
|
+
|
2251
|
+
|
2252
|
+
# WH implementation of the Ruby count.
|
2253
|
+
def scount(obj = nil, &ruby_block)
|
2254
|
+
return self.make_iterator("count",obj,&ruby_block)
|
2255
|
+
end
|
2256
|
+
|
2257
|
+
# HW implementation of the Ruby cycle.
|
2258
|
+
def scycle(n = nil,&ruby_block)
|
2259
|
+
return self.make_iterator("cycle",n,&ruby_block)
|
2260
|
+
end
|
2261
|
+
|
2262
|
+
# HW implementation of the Ruby find.
|
2263
|
+
# NOTE: contrary to Ruby, if_none_proc is mandatory since there is no
|
2264
|
+
# nil in HW. Moreover, the argument can also be a value.
|
2265
|
+
def sfind(if_none_proc, &ruby_block)
|
2266
|
+
return self.make_iterator("find",if_none_proc,&ruby_block)
|
2267
|
+
end
|
2268
|
+
|
2269
|
+
# HW implementation of the Ruby drop.
|
2270
|
+
def sdrop(n)
|
2271
|
+
return self.make_iterator("drop",n)
|
2272
|
+
end
|
2273
|
+
|
2274
|
+
# HW implementation of the Ruby drop_while.
|
2275
|
+
def sdrop_while(&ruby_block)
|
2276
|
+
return self.make_iterator("drop_while",&ruby_block)
|
2277
|
+
end
|
2278
|
+
|
2279
|
+
# HW implementation of the Ruby each_cons
|
2280
|
+
def seach_cons(n,&ruby_block)
|
2281
|
+
return self.make_iterator("each_cons",n,&ruby_block)
|
2282
|
+
end
|
2283
|
+
|
2284
|
+
# HW implementation of the Ruby each_entry.
|
2285
|
+
# NOTE: to do, or may be not.
|
2286
|
+
def seach_entry(*args,&ruby_block)
|
2287
|
+
raise "seach_entry is not supported yet."
|
2288
|
+
end
|
2289
|
+
|
2290
|
+
# HW implementation of the Ruby each_slice
|
2291
|
+
def seach_slice(n,&ruby_block)
|
2292
|
+
return self.make_iterator("each_slice",n,&ruby_block)
|
2293
|
+
end
|
2294
|
+
|
2295
|
+
# HW implementation of the Ruby each_with_index.
|
2296
|
+
def seach_with_index(*args,&ruby_block)
|
2297
|
+
return self.make_iterator("each_with_index",*args,&ruby_block)
|
2298
|
+
end
|
2299
|
+
|
2300
|
+
# HW implementation of the Ruby each_with_object.
|
2301
|
+
def seach_with_object(obj,&ruby_block)
|
2302
|
+
return self.make_iterator("each_with_object",obj,&ruby_block)
|
2303
|
+
end
|
2304
|
+
|
2305
|
+
# HW implementation of the Ruby to_a.
|
2306
|
+
def sto_a
|
2307
|
+
return self.make_iterator("to_a")
|
2308
|
+
end
|
2309
|
+
|
2310
|
+
# HW implementation of the Ruby select.
|
2311
|
+
def sselect(&ruby_block)
|
2312
|
+
return self.make_iterator("select",&ruby_block)
|
2313
|
+
end
|
2314
|
+
|
2315
|
+
# HW implementation of the Ruby find_index.
|
2316
|
+
def sfind_index(obj = nil, &ruby_block)
|
2317
|
+
return self.make_iterator("find_index",obj,&ruby_block)
|
2318
|
+
end
|
2319
|
+
|
2320
|
+
# HW implementation of the Ruby first.
|
2321
|
+
def sfirst(n=1)
|
2322
|
+
return self.make_iterator("first",n)
|
2323
|
+
end
|
2324
|
+
|
2325
|
+
# HW implementation of the Ruby grep.
|
2326
|
+
# NOTE: to do, or may be not.
|
2327
|
+
def sgrep(*args,&ruby_block)
|
2328
|
+
raise "sgrep is not supported yet."
|
2329
|
+
end
|
2330
|
+
|
2331
|
+
# HW implementation of the Ruby grep_v.
|
2332
|
+
# NOTE: to do, or may be not.
|
2333
|
+
def sgrep_v(*args,&ruby_block)
|
2334
|
+
raise "sgrep_v is not supported yet."
|
2335
|
+
end
|
2336
|
+
|
2337
|
+
# HW implementation of the Ruby group_by.
|
2338
|
+
# NOTE: to do, or may be not.
|
2339
|
+
def sgroup_by(*args,&ruby_block)
|
2340
|
+
raise "sgroup_by is not supported yet."
|
2341
|
+
end
|
2342
|
+
|
2343
|
+
# HW implementation of the Ruby include?
|
2344
|
+
def sinclude?(obj)
|
2345
|
+
return self.make_iterator("include?",obj)
|
2346
|
+
end
|
2347
|
+
|
2348
|
+
# HW implementation of the Ruby inject.
|
2349
|
+
def sinject(*args,&ruby_block)
|
2350
|
+
return self.make_iterator("inject",*args,&ruby_block)
|
2351
|
+
end
|
2352
|
+
|
2353
|
+
# HW implementation of the Ruby reduce.
|
2354
|
+
def sreduce
|
2355
|
+
return self.make_iterator("reduce",*args,&ruby_block)
|
2356
|
+
end
|
2357
|
+
|
2358
|
+
|
2359
|
+
# HW implementation of the Ruby lazy.
|
2360
|
+
# NOTE: to do, or may be not.
|
2361
|
+
def slazy(*args,&ruby_block)
|
2362
|
+
raise "slazy is not supported yet."
|
2363
|
+
end
|
2364
|
+
|
2365
|
+
# HW implementation of the Ruby max.
|
2366
|
+
def smax(n = nil, &ruby_block)
|
2367
|
+
return self.make_iterator("max",n,&ruby_block)
|
2368
|
+
end
|
2369
|
+
|
2370
|
+
# HW implementation of the Ruby max_by.
|
2371
|
+
def smax_by(n = nil, &ruby_block)
|
2372
|
+
return self.make_iterator("max_by",n,&ruby_block)
|
2373
|
+
end
|
2374
|
+
|
2375
|
+
# HW implementation of the Ruby min.
|
2376
|
+
def smin(n = nil, &ruby_block)
|
2377
|
+
return self.make_iterator("min",n,&ruby_block)
|
2378
|
+
end
|
2379
|
+
|
2380
|
+
# HW implementation of the Ruby min_by.
|
2381
|
+
def smin_by(n = nil, &ruby_block)
|
2382
|
+
return self.make_iterator("min_by",n,&ruby_block)
|
2383
|
+
end
|
2384
|
+
|
2385
|
+
# HW implementation of the Ruby minmax.
|
2386
|
+
def sminmax(&ruby_block)
|
2387
|
+
return self.make_iterator("minmax",&ruby_block)
|
2388
|
+
end
|
2389
|
+
|
2390
|
+
# HW implementation of the Ruby minmax_by.
|
2391
|
+
def sminmax_by(&ruby_block)
|
2392
|
+
return self.make_iterator("minmax_by",&ruby_block)
|
2393
|
+
end
|
2394
|
+
|
2395
|
+
# Tell if none of the elements respects a given criterion given either
|
2396
|
+
# as +arg+ or as block.
|
2397
|
+
def snone?(arg = nil,&ruby_block)
|
2398
|
+
return self.make_iterator("none?",arg,&ruby_block)
|
2399
|
+
end
|
2400
|
+
|
2401
|
+
# Tell if one and only one of the elements respects a given criterion
|
2402
|
+
# given either as +arg+ or as block.
|
2403
|
+
def sone?(arg = nil,&ruby_block)
|
2404
|
+
return self.make_iterator("one?",arg,&ruby_block)
|
2405
|
+
end
|
2406
|
+
|
2407
|
+
# HW implementation of the Ruby partition.
|
2408
|
+
# NOTE: to do, or may be not.
|
2409
|
+
def spartition(*args,&ruby_block)
|
2410
|
+
raise "spartition is not supported yet."
|
2411
|
+
end
|
2412
|
+
|
2413
|
+
# HW implementatiob of the Ruby reject.
|
2414
|
+
def sreject(&ruby_block)
|
2415
|
+
return self.make_iterator("reject",&ruby_block)
|
2416
|
+
end
|
2417
|
+
|
2418
|
+
# HW implementatiob of the Ruby reverse_each.
|
2419
|
+
def sreverse_each(*args,&ruby_block)
|
2420
|
+
return self.make_iterator("reverse_each",*args,&ruby_block)
|
2421
|
+
end
|
2422
|
+
|
2423
|
+
# HW implementation of the Ruby slice_after.
|
2424
|
+
# NOTE: to do, or may be not.
|
2425
|
+
def sslice_after(pattern = nil,&ruby_block)
|
2426
|
+
raise "sslice_after is not supported yet."
|
2427
|
+
end
|
2428
|
+
|
2429
|
+
# HW implementation of the Ruby slice_before.
|
2430
|
+
# NOTE: to do, or may be not.
|
2431
|
+
def sslice_before(*args,&ruby_block)
|
2432
|
+
raise "sslice_before is not supported yet."
|
2433
|
+
end
|
2434
|
+
|
2435
|
+
# HW implementation of the Ruby slice_when.
|
2436
|
+
# NOTE: to do, or may be not.
|
2437
|
+
def sslice_when(*args,&ruby_block)
|
2438
|
+
raise "sslice_before is not supported yet."
|
2439
|
+
end
|
2440
|
+
|
2441
|
+
# Merge two arrays in order, for ssort only.
|
2442
|
+
def ssort_merge(arI, arO, first, middle, last, &ruby_block)
|
2443
|
+
return self.make_iterator("sort_merge",arI,arO,first,middle,last,&ruby_block)
|
2444
|
+
end
|
2445
|
+
|
2446
|
+
# HW implementation of the Ruby sort.
|
2447
|
+
def ssort(&ruby_block)
|
2448
|
+
return self.make_iterator("sort",&ruby_block)
|
2449
|
+
end
|
2450
|
+
|
2451
|
+
# HW implementation of the Ruby sort.
|
2452
|
+
def ssort_by(&ruby_block)
|
2453
|
+
return self.make_iterator("sort_by",&ruby_block)
|
2454
|
+
end
|
2455
|
+
|
2456
|
+
# HW implementation of the Ruby sum.
|
2457
|
+
def ssum(initial_value = nil,&ruby_block)
|
2458
|
+
return self.make_iterator("sum",initial_value,&ruby_block)
|
2459
|
+
end
|
2460
|
+
|
2461
|
+
# The HW implementation of the Ruby take.
|
2462
|
+
def stake(n)
|
2463
|
+
return self.make_iterator("take",n)
|
2464
|
+
end
|
2465
|
+
|
2466
|
+
# The HW implementation of the Ruby take_while.
|
2467
|
+
def stake_while(&ruby_block)
|
2468
|
+
return self.make_iterator("take_while",&ruby_block)
|
2469
|
+
end
|
2470
|
+
|
2471
|
+
# HW implementation of the Ruby tally.
|
2472
|
+
# NOTE: to do, or may be not.
|
2473
|
+
def stally(h = nil)
|
2474
|
+
raise "stally is not supported yet."
|
2475
|
+
end
|
2476
|
+
|
2477
|
+
# HW implementation of the Ruby to_h.
|
2478
|
+
# NOTE: to do, or may be not.
|
2479
|
+
def sto_h(h = nil)
|
2480
|
+
raise "sto_h is not supported yet."
|
2481
|
+
end
|
2482
|
+
|
2483
|
+
# HW implementation of the Ruby uniq.
|
2484
|
+
def suniq(&ruby_block)
|
2485
|
+
return self.make_iterator("uniq",&ruby_block)
|
2486
|
+
end
|
2487
|
+
|
2488
|
+
# HW implementation of the Ruby zip.
|
2489
|
+
# NOTE: for now szip is deactivated untile tuples are properly
|
2490
|
+
# handled by HDLRuby.
|
2491
|
+
def szip(obj,&ruby_block)
|
2492
|
+
return self.make_iterator("zip",obj,&ruby_block)
|
2493
|
+
end
|
2494
|
+
|
2495
|
+
# Iterator on the +num+ next elements.
|
2496
|
+
# *NOTE*:
|
2497
|
+
# - Stop iteration when the end of the range is reached or when there
|
2498
|
+
# are no elements left
|
2499
|
+
# - This is not a method from Ruby but one specific for hardware where
|
2500
|
+
# creating a array is very expensive.
|
2501
|
+
def seach_nexts(num,&ruby_block)
|
2502
|
+
return self.seach.snexts(num,&ruby_block)
|
2503
|
+
end
|
2504
|
+
end
|
2505
|
+
|
2506
|
+
|
2507
|
+
# Describes a SW implementation of a signal.
|
2508
|
+
class SignalI < Expression
|
2509
|
+
using RubyHDL::High
|
2510
|
+
attr_reader :type, :name #, :content
|
2511
|
+
# Create a new signal with type +type+ and name +name+.
|
2512
|
+
def initialize(type,name)
|
2513
|
+
@type = type.to_type
|
2514
|
+
@name = name.to_sym
|
2515
|
+
# @content = nil # The content is the Ruby value, not the HW description one!
|
2516
|
+
end
|
2517
|
+
|
2518
|
+
# Tell if the signal is an array.
|
2519
|
+
def array?
|
2520
|
+
return @type.base.is_a?(TypeVector)
|
2521
|
+
end
|
2522
|
+
|
2523
|
+
# # Convert to a value.
|
2524
|
+
# def to_value
|
2525
|
+
# return @content.to_value
|
2526
|
+
# end
|
2527
|
+
|
2528
|
+
# Sets the content of the signal.
|
2529
|
+
# def content=(value)
|
2530
|
+
# @content = value
|
2531
|
+
# end
|
2532
|
+
|
2533
|
+
# Convert to ruby code.
|
2534
|
+
def to_ruby
|
2535
|
+
# return self.name.to_s + ".content"
|
2536
|
+
return "__" + self.name.to_s
|
2537
|
+
end
|
2538
|
+
|
2539
|
+
# Gets the value of the signal.
|
2540
|
+
def value
|
2541
|
+
return TOPLEVEL_BINDING.eval(self.to_ruby)
|
2542
|
+
end
|
2543
|
+
|
2544
|
+
# Sets the value of the signal.
|
2545
|
+
def value=(val)
|
2546
|
+
return TOPLEVEL_BINDING.eval("#{self.to_ruby} = #{val}")
|
2547
|
+
end
|
2548
|
+
|
2549
|
+
# Convert to an integer.
|
2550
|
+
def to_i
|
2551
|
+
# return @content.to_i
|
2552
|
+
# return binding.local_variable_get(to_ruby.to_sym).to_i
|
2553
|
+
return self.value.to_i
|
2554
|
+
end
|
2555
|
+
|
2556
|
+
# Convert to an float.
|
2557
|
+
def to_f
|
2558
|
+
# return @content.to_f
|
2559
|
+
# return binding.local_variable_get(to_ruby.to_sym).to_f
|
2560
|
+
return self.value.to_f
|
2561
|
+
end
|
2562
|
+
|
2563
|
+
# Convert to a string.
|
2564
|
+
def to_s
|
2565
|
+
# return @content.to_s
|
2566
|
+
# return binding.local_variable_get(to_ruby.to_sym).to_s
|
2567
|
+
return self.value.to_s
|
2568
|
+
end
|
2569
|
+
end
|
2570
|
+
|
2571
|
+
|
2572
|
+
# Describes a SW implementation of a block.
|
2573
|
+
class Sblock < SblockTop
|
2574
|
+
using RubyHDL::High
|
2575
|
+
|
2576
|
+
attr_reader :sequencer
|
2577
|
+
|
2578
|
+
# Create a new block for sequencer +sequencer+ and fill it by
|
2579
|
+
# executing +ruby_block+
|
2580
|
+
def initialize(sequencer,&ruby_block)
|
2581
|
+
super()
|
2582
|
+
# Sets the sequencer.
|
2583
|
+
@sequencer = sequencer
|
2584
|
+
# Initialize the statements.
|
2585
|
+
@statements = []
|
2586
|
+
# Push the new sblock on top of the stack.
|
2587
|
+
RubyHDL::High.push_sblock(self)
|
2588
|
+
# Fill it.
|
2589
|
+
self.instance_eval(&ruby_block)
|
2590
|
+
# Pop the new sblock.
|
2591
|
+
RubyHDL::High.pop_sblock
|
2592
|
+
end
|
2593
|
+
|
2594
|
+
# Add a new statement to the block.
|
2595
|
+
def add(statement)
|
2596
|
+
# Add the statement.
|
2597
|
+
@statements.push(statement)
|
2598
|
+
# # If the statement is a transmit, schedule the corresponding
|
2599
|
+
# # signal for final update.
|
2600
|
+
# if statement.is_a?(Transmit) then
|
2601
|
+
# @sequencer.to_update(statement.left)
|
2602
|
+
# end
|
2603
|
+
statement
|
2604
|
+
end
|
2605
|
+
alias_method :<<, :add
|
2606
|
+
|
2607
|
+
# Delete a statement.
|
2608
|
+
def delete(statement)
|
2609
|
+
@statements.delete(statement)
|
2610
|
+
end
|
2611
|
+
|
2612
|
+
# Unshift a new statement.
|
2613
|
+
def unshift(statement)
|
2614
|
+
@statements.unshift(statement)
|
2615
|
+
end
|
2616
|
+
|
2617
|
+
|
2618
|
+
# Convert to ruby code.
|
2619
|
+
def to_ruby
|
2620
|
+
return @statements.map do |stmnt|
|
2621
|
+
stmnt.to_ruby + "\n"
|
2622
|
+
end.join
|
2623
|
+
end
|
2624
|
+
|
2625
|
+
# The interface for describing statements and expressions.
|
2626
|
+
|
2627
|
+
# Mark a step.
|
2628
|
+
def step
|
2629
|
+
self << RubyHDL::High::Step.new(@sequencer)
|
2630
|
+
end
|
2631
|
+
|
2632
|
+
# Mark several steps.
|
2633
|
+
def steps(num)
|
2634
|
+
num.times { self.step }
|
2635
|
+
end
|
2636
|
+
|
2637
|
+
# Breaks current iteration.
|
2638
|
+
def sbreak
|
2639
|
+
self << RubyHDL::High::Sbreak.new(@sequencer)
|
2640
|
+
end
|
2641
|
+
|
2642
|
+
# Continues current iteration.
|
2643
|
+
def scontinue
|
2644
|
+
self << RubyHDL::High::Scontinue.new(@sequencer)
|
2645
|
+
end
|
2646
|
+
|
2647
|
+
# Terminates the sequencer.
|
2648
|
+
def sterminate
|
2649
|
+
self << RubyHDL::High::Sterminate.new(@sequencer)
|
2650
|
+
end
|
2651
|
+
|
2652
|
+
# Create a sequential if statement on +cond+.
|
2653
|
+
def sif(cond, &ruby_block)
|
2654
|
+
self << RubyHDL::High::Sif.new(@sequencer,cond,&ruby_block)
|
2655
|
+
end
|
2656
|
+
|
2657
|
+
# Create a sequential elsif statement on +cond+.
|
2658
|
+
def selsif(cond, &ruby_block)
|
2659
|
+
self.statements[-1].selsif(&ruby_block)
|
2660
|
+
end
|
2661
|
+
|
2662
|
+
# Create a sequential else statement.
|
2663
|
+
def selse(&ruby_block)
|
2664
|
+
self.statements[-1].selse(&ruby_block)
|
2665
|
+
end
|
2666
|
+
|
2667
|
+
# Wait a given condition.
|
2668
|
+
def swait(cond)
|
2669
|
+
self.swhile(~cond)
|
2670
|
+
end
|
2671
|
+
|
2672
|
+
# Create a sequential while statement on +cond+.
|
2673
|
+
def swhile(cond,&ruby_block)
|
2674
|
+
self << RubyHDL::High::Swhile.new(@sequencer,cond,&ruby_block)
|
2675
|
+
end
|
2676
|
+
|
2677
|
+
# Create a sequential infinite loop statement.
|
2678
|
+
def sloop(&ruby_block)
|
2679
|
+
self << RubyHDL::High::Sloop.new(@sequencer,&ruby_block)
|
2680
|
+
end
|
2681
|
+
|
2682
|
+
# Create a sequential for statement iterating over the elements
|
2683
|
+
# of +expr+.
|
2684
|
+
def sfor(expr,&ruby_block)
|
2685
|
+
# Ensures there is a ruby block to avoid returning an enumerator
|
2686
|
+
# (returning an enumerator would be confusing for a for statement).
|
2687
|
+
ruby_block = proc {} unless ruby_block
|
2688
|
+
expr.seach.with_index(&ruby_block)
|
2689
|
+
end
|
2690
|
+
|
2691
|
+
# The SW-specific statements and expressions.
|
2692
|
+
|
2693
|
+
# Mark a synchronisation.
|
2694
|
+
# For software only: stop the current sequencer for allowing
|
2695
|
+
# sharing of variables with other ones.
|
2696
|
+
def sync
|
2697
|
+
self << RubyHDL::High::Sync.new
|
2698
|
+
end
|
2699
|
+
|
2700
|
+
# Some arbirary Ruby code.
|
2701
|
+
def ruby(&ruby_block)
|
2702
|
+
self << RubyHDL::High::Ruby.new(&ruby_block)
|
2703
|
+
end
|
2704
|
+
end
|
2705
|
+
|
2706
|
+
|
2707
|
+
|
2708
|
+
|
2709
|
+
# Describes a SW implmentation of a sequencer.
|
2710
|
+
class SequencerT
|
2711
|
+
|
2712
|
+
# The source code (in ruby).
|
2713
|
+
attr_reader :source
|
2714
|
+
|
2715
|
+
# The clock counter.
|
2716
|
+
attr_reader :clk
|
2717
|
+
|
2718
|
+
# Create a new sequencer block, with clock counter +clk+ and
|
2719
|
+
# run control +start+.
|
2720
|
+
# Note: if +clk+ is not provided no clock counter will be generate.
|
2721
|
+
def initialize(clk = nil, start = nil, &ruby_block)
|
2722
|
+
# Sets the clock counter and start control.
|
2723
|
+
@clk = clk
|
2724
|
+
@start = start
|
2725
|
+
if @start then
|
2726
|
+
this = self
|
2727
|
+
# Make @start a controlling signal.
|
2728
|
+
@start.define_singleton_method(:<=,val) do
|
2729
|
+
this.resume if val.to_i == 1
|
2730
|
+
end
|
2731
|
+
end
|
2732
|
+
# # Create the set of signals to update.
|
2733
|
+
# @to_updates = []
|
2734
|
+
# Create the main block.
|
2735
|
+
@sblock = RubyHDL::High::Sblock.new(self,&ruby_block)
|
2736
|
+
# Build the Ruby code.
|
2737
|
+
@source = ""
|
2738
|
+
@code = nil
|
2739
|
+
self.build
|
2740
|
+
end
|
2741
|
+
|
2742
|
+
# # Set a signal to be updated at the end of the sequencer.
|
2743
|
+
# def to_update(signal)
|
2744
|
+
# signal = signal.final_base unless signal.is_a?(SignalI)
|
2745
|
+
# @to_updates << signal
|
2746
|
+
# end
|
2747
|
+
|
2748
|
+
# # Iterator on the updates.
|
2749
|
+
# def each_to_update(&ruby_block)
|
2750
|
+
# # No ruby block? Return an enumerator.
|
2751
|
+
# return to_enum(:each_to_update) unless ruby_block
|
2752
|
+
# @to_updates.each(&ruby_block)
|
2753
|
+
# end
|
2754
|
+
#
|
2755
|
+
|
2756
|
+
# Build the ruby code.
|
2757
|
+
def build
|
2758
|
+
this = self
|
2759
|
+
@source = <<-BUILD
|
2760
|
+
#{RubyHDL::High.global_sblock.each_signal.map do |signal|
|
2761
|
+
signal.to_ruby + " = " + (signal.array? ? "[]" : "nil") + " unless defined?(" + signal.to_ruby + ")"
|
2762
|
+
end.join("\n")}
|
2763
|
+
Fiber.new do
|
2764
|
+
#{@sblock.to_ruby}
|
2765
|
+
end
|
2766
|
+
BUILD
|
2767
|
+
# puts "building code_txt=" + @source
|
2768
|
+
@code = TOPLEVEL_BINDING.eval(@source)
|
2769
|
+
end
|
2770
|
+
|
2771
|
+
# Handling of the clock if any.
|
2772
|
+
|
2773
|
+
# Generate a clock up of +count+ cycles if any clock.
|
2774
|
+
def clk_up(count = 1)
|
2775
|
+
if @clk then
|
2776
|
+
return "#{clk.to_ruby} += #{count.to_i}"
|
2777
|
+
else
|
2778
|
+
return ""
|
2779
|
+
end
|
2780
|
+
end
|
2781
|
+
|
2782
|
+
|
2783
|
+
# Control of the sequencer.
|
2784
|
+
|
2785
|
+
# Executes the sequencer.
|
2786
|
+
def resume
|
2787
|
+
# @code.call
|
2788
|
+
@code.resume
|
2789
|
+
end
|
2790
|
+
alias_method :call, :resume
|
2791
|
+
|
2792
|
+
# Check is the sequencer can still be resumed.
|
2793
|
+
def alive?
|
2794
|
+
@code.alive?
|
2795
|
+
end
|
2796
|
+
|
2797
|
+
end
|
2798
|
+
|
2799
|
+
|
2800
|
+
|
2801
|
+
|
2802
|
+
|
2803
|
+
# Create a new sequencer block, with clock counter +clk+ and
|
2804
|
+
# run control +start+
|
2805
|
+
def sequencer(clk = nil, start = nil, &ruby_block)
|
2806
|
+
return SequencerT.new(clk,start,&ruby_block)
|
2807
|
+
end
|
2808
|
+
|
2809
|
+
# Creates an sequencer enumerator using a specific block access.
|
2810
|
+
# - +typ+ is the data type of the elements.
|
2811
|
+
# - +size+ is the number of elements, nil if not relevant.
|
2812
|
+
# - +access+ is the block implementing the access method.
|
2813
|
+
# def senumerator(typ,size,&access)
|
2814
|
+
def senumerator(typ,size = nil,&access)
|
2815
|
+
return SEnumeratorBase.new(typ,size,&access)
|
2816
|
+
end
|
2817
|
+
|
2818
|
+
|
2819
|
+
end
|
2820
|
+
|
2821
|
+
|
2822
|
+
|
2823
|
+
include RubyHDL::High
|
2824
|
+
using RubyHDL::High
|
2825
|
+
|