Module: HDLRuby::High::Std::HEnumerable

Included in:
HEnumerator
Defined in:
lib/HDLRuby/std/hruby_enum.rb

Overview

Module adding hardware enumerator functionalities to object including the to_a method.

Instance Method Summary collapse

Instance Method Details

#call(*args, &ruby_block) ⇒ Object

Specific to HDLRuby: inject with no default value through the call operator.



351
352
353
# File 'lib/HDLRuby/std/hruby_enum.rb', line 351

def call(*args, &ruby_block)
  return self.hinject(*args,&ruby_block)
end

#h_to_aObject

Convert to an array.



17
18
19
20
21
# File 'lib/HDLRuby/std/hruby_enum.rb', line 17

def h_to_a
  res = []
  self.heach {|e| res << e }
  return res
end

#hall?(arg = nil, &ruby_block) ⇒ Boolean

Tell if all the elements respect a given criterion given either as +arg+ or as block.

Returns:

  • (Boolean)


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/HDLRuby/std/hruby_enum.rb', line 35

def hall?(arg = nil, &ruby_block)
  if self.hsize < 1 then
    # Empty, so always true.
    return 1
  end
  comp = []
  if arg then
    # Compare each element to arg in parallel.
    comp = self.hmap do |elem|
      elem == arg
    end
  elsif ruby_block then
    # Use the ruby block in parallel.
    comp = self.hmap(&ruby_block)
  else
    # Nothing to check.
    return 1
  end
  # Reduce the result.
  return comp.reduce(&:&)
end

#hany?(arg = nil, &ruby_block) ⇒ Boolean

Tell if any of the elements respects a given criterion given either as +arg+ or as block.

Returns:

  • (Boolean)


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/HDLRuby/std/hruby_enum.rb', line 59

def hany?(arg = nil,&ruby_block)
  if self.hsize < 1 then
    # Empty, so always false.
    return 0
  end
  comp = []
  if arg then
    # Compare each element to arg in parallel.
    comp = self.hmap do |elem|
      elem == arg
    end
  elsif ruby_block then
    # Use the ruby block in parallel.
    comp = self.hmap(&ruby_block)
  else
    # Nothing to check.
    return 0
  end
  # Reduce the result.
  return comp.reduce(&:|)
end

#hchain(arg) ⇒ Object

Returns an HEnumerator generated from current enumerable and +arg+



82
83
84
85
# File 'lib/HDLRuby/std/hruby_enum.rb', line 82

def hchain(arg)
  # return self.heach + arg
  return self.hto_a + arg.hto_a
end

#hchunk(*args, &ruby_block) ⇒ Object

HW implementation of the Ruby chunk. NOTE: to do, or may be not.



89
90
91
# File 'lib/HDLRuby/std/hruby_enum.rb', line 89

def hchunk(*args,&ruby_block)
  raise "hchunk is not supported yet."
end

#hchunk_while(*args, &ruby_block) ⇒ Object

HW implementation of the Ruby chunk_while. NOTE: to do, or may be not.



95
96
97
# File 'lib/HDLRuby/std/hruby_enum.rb', line 95

def hchunk_while(*args,&ruby_block)
  raise "hchunk_while is not supported yet."
end

#hcompactObject

HW implementation of the Ruby compact.



124
125
126
# File 'lib/HDLRuby/std/hruby_enum.rb', line 124

def hcompact
  raise "hcompact is not supported yet."
end

#hcount(arg = nil, &ruby_block) ⇒ Object

HW implementation of the Ruby count.



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/HDLRuby/std/hruby_enum.rb', line 130

def hcount(arg = nil, &ruby_block)
  if self.hsize < 1 then
    # Empty, so always false.
    return 0
  end
  comp = []
  if arg then
    # Compare each element to arg in parallel.
    comp = self.hmap do |elem|
      elem == arg
    end
  elsif ruby_block then
    # Use the ruby block in parallel.
    comp = self.hmap(&ruby_block)
  else
    # Nothing to check, return the size.
    return self.hsize
  end
  # Reduce the result.
  return comp.reduce(&:+)
end

#hcycle(n = nil, &ruby_block) ⇒ Object

HW implementation of the Ruby cycle.



153
154
155
# File 'lib/HDLRuby/std/hruby_enum.rb', line 153

def hcycle(n = nil,&ruby_block)
  raise "hcycle is not supported yet."
end

#hdrop(n) ⇒ Object

HW implementation of the Ruby drop.



181
182
183
184
185
186
187
188
189
190
191
# File 'lib/HDLRuby/std/hruby_enum.rb', line 181

def hdrop(n)
  # return self.heach.drop(n)
  res = []
  size = self.hsize
  self.heach do |e|
    #   break if n == size
    n += 1
    res << e if n < size
  end
  return res
end

#hdrop_while(&ruby_block) ⇒ Object

HW implementation of the Ruby drop_while.



194
195
196
# File 'lib/HDLRuby/std/hruby_enum.rb', line 194

def hdrop_while(&ruby_block)
  raise "hdrop_while is not supported yet."
end

#heach_cons(n, &ruby_block) ⇒ Object

HW implementation of the Ruby each_cons



199
200
201
202
203
204
205
206
# File 'lib/HDLRuby/std/hruby_enum.rb', line 199

def heach_cons(n,&ruby_block)
  # No block given? Generate a new wrapper enumerator for heach_cons.
  if !ruby_block then
    return HEnumeratorWrapper.new(self,:heach_cons,n)
  end
  # return self.heach.each_cons(n,&ruby_block)
  return self.hto_a.each_cons(n,&ruby_block)
end

#heach_entry(*args, &ruby_block) ⇒ Object

HW implementation of the Ruby each_entry. NOTE: to do, or may be not.



210
211
212
# File 'lib/HDLRuby/std/hruby_enum.rb', line 210

def heach_entry(*args,&ruby_block)
  raise "heach_entry is not supported yet."
end

#heach_nexts(num, &ruby_block) ⇒ Object

Iterator on the +num+ next elements. NOTE:

  • Stop iteration when the end of the range is reached or when there are no elements left
  • This is not a method from Ruby but one specific for hardware where creating a array is very expensive.


747
748
749
# File 'lib/HDLRuby/std/hruby_enum.rb', line 747

def heach_nexts(num,&ruby_block)
  raise "heach_nexts is not supported yet."
end

#heach_range(rng, &ruby_block) ⇒ Object

Iterator on each of the elements in range +rng+. NOTE:

  • Stop iteration when the end of the range is reached or when there are no elements left
  • This is not a method from Ruby but one specific for hardware where creating a array is very expensive.


29
30
31
# File 'lib/HDLRuby/std/hruby_enum.rb', line 29

def heach_range(rng,&ruby_block)
  return self.heach.each_range(rng,&ruby_block)
end

#heach_slice(n, &ruby_block) ⇒ Object

HW implementation of the Ruby each_slice



215
216
217
218
219
220
221
222
# File 'lib/HDLRuby/std/hruby_enum.rb', line 215

def heach_slice(n,&ruby_block)
  # No block given? Generate a new wrapper enumerator for heach_slice.
  if !ruby_block then
    return HEnumeratorWrapper.new(self,:heach_slice,n)
  end
  # return self.heach.each_slice(n,&ruby_block)
  return self.hto_a.each_slice(n,&ruby_block)
end

#heach_with_index(*args, &ruby_block) ⇒ Object

HW implementation of the Ruby each_with_index.



225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/HDLRuby/std/hruby_enum.rb', line 225

def heach_with_index(*args,&ruby_block)
  # No block given? Generate a new wrapper enumerator for
  # heach_with_index.
  if !ruby_block then
    return HEnumeratorWrapper.new(self,:heach_with_index)
  end
  # self.heach.each_with_index(*args,&ruby_block)
  idx = 0
  self.heach do |e|
    ruby_block.call(*args,e,idx)
    idx += 1
  end
end

#heach_with_object(obj, &ruby_block) ⇒ Object

HW implementation of the Ruby each_with_object.



240
241
242
243
244
245
246
247
248
# File 'lib/HDLRuby/std/hruby_enum.rb', line 240

def heach_with_object(obj,&ruby_block)
  # No block given? Generate a new wrapper enumerator for
  # heach_with_object.
  if !ruby_block then
    return HEnumeratorWrapper.new(self,:heach_with_object)
  end
  # self.heach.with_object(obj,&ruby_block)
  self.heach { |e| ruby_block.call(e,obj,&ruby_block) }
end

#hfind(ifnone = proc { 0 }, &ruby_block) ⇒ Object

HW implementation of the Ruby find. NOTE: contrary to Ruby, by default ifnone is 0 and not nil.



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/HDLRuby/std/hruby_enum.rb', line 159

def hfind(ifnone = proc { 0 }, &ruby_block)
  # No block given? Generate a new wrapper enumerator for sfind.
  if !ruby_block then
    return HEnumeratorWrapper.new(self,:hfind,ifnone)
  end
  if self.hsize < 1 then
    # Empty, so always not found.
    return ifnone.call
  end
  # Convert to an array.
  ar = self.hto_a
  # Use the ruby block in parallel.
  comp = ar.map { |elem| ruby_block.call(elem) }
  # Generate the look up circuit.
  res = HDLRuby::High.top_user.mux(comp[-1],ifnone.call,ar[-1])
  (self.hsize-1).times do |i|
    res = HDLRuby::High.top_user.mux(comp[-i-2],res,ar[-i-2])
  end
  return res
end

#hfind_index(obj = nil, &ruby_block) ⇒ Object

HW implementation of the Ruby find_index.



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/HDLRuby/std/hruby_enum.rb', line 267

def hfind_index(obj = nil, &ruby_block)
  # No block given nor obj? Generate a new wrapper enumerator for
  # hfind.
  if !ruby_block && !obj then
    return HEnumeratorWrapper.new(self,:hfind)
  end
  if self.hsize < 1 then
    # Empty, so always not found.
    return -1
  end
  # If there is an objet, look for it.
  ruby_block = proc { |e| e == obj } if obj
  # Convert to an array.
  ar = self.hto_a
  size =ar.size
  # Use the ruby block in parallel.
  comp = self.hmap { |elem| ruby_block.call(elem) }
  # Generate the look up circuit.
  res = HDLRuby::High.top_user.mux(comp[-1],-1,size-1)
  (self.hsize-1).times do |i|
    res = HDLRuby::High.top_user.mux(comp[-i-2],res,size-i-2)
  end
  return res
end

#hfirst(n = 1) ⇒ Object

HW implementation of the Ruby first.



293
294
295
296
297
298
299
300
301
302
# File 'lib/HDLRuby/std/hruby_enum.rb', line 293

def hfirst(n=1)
  # return self.heach.first(n)
  res = []
  self.heach do |e|
    # break if n == 0
    res << e if n > 0
    n -= 1
  end
  return res
end

#hflat_map(&ruby_block) ⇒ Object

HW implementation of the Ruby flat_map.



113
114
115
116
117
118
119
120
121
# File 'lib/HDLRuby/std/hruby_enum.rb', line 113

def hflat_map(&ruby_block)
  # No block given? Generate a new wrapper enumerator for smap.
  if !ruby_block then
    return HEnumeratorWrapper.new(self,:hmap)
  end
  # A block given? Create the result HEnumerable (a Ruby array).
  # return self.heach.flat_map(&ruby_block)
  return self.hto_a.flat_map(&ruby_block)
end

#hgrep(*args, &ruby_block) ⇒ Object

HW implementation of the Ruby grep. NOTE: to do, or may be not.



306
307
308
# File 'lib/HDLRuby/std/hruby_enum.rb', line 306

def hgrep(*args,&ruby_block)
  raise "hgrep is not supported yet."
end

#hgrep_v(*args, &ruby_block) ⇒ Object

HW implementation of the Ruby grep_v. NOTE: to do, or may be not.



312
313
314
# File 'lib/HDLRuby/std/hruby_enum.rb', line 312

def hgrep_v(*args,&ruby_block)
  raise "hgrep_v is not supported yet."
end

#hgroup_by(*args, &ruby_block) ⇒ Object

HW implementation of the Ruby group_by. NOTE: to do, or may be not.



318
319
320
# File 'lib/HDLRuby/std/hruby_enum.rb', line 318

def hgroup_by(*args,&ruby_block)
  raise "hgroup_by is not supported yet."
end

#hinclude?(obj) ⇒ Boolean

HW implementation of the Ruby include?

Returns:

  • (Boolean)


323
324
325
# File 'lib/HDLRuby/std/hruby_enum.rb', line 323

def hinclude?(obj)
  return self.hany?(obj)
end

#hinject(*args, &ruby_block) ⇒ Object Also known as: hreduce

HW implementation of the Ruby inject.



328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/HDLRuby/std/hruby_enum.rb', line 328

def hinject(*args, &ruby_block)
  # return self.heach.inject(*args,&ruby_block)
  # return self.hto_a.inject(*args,&ruby_block)
  if ruby_block then
    # Case when a block is given.
    res = args[0]
    self.heach do |e|
      res = res ? ruby_block.call(res,e) : e
    end
  else
    # Case when a symbol is given.
    sym, res = args[0], args[1]
    self.heach do |e|
      res = res ? res.send(sym,e) : e
    end
  end
  return res
end

#hlazy(*args, &ruby_block) ⇒ Object

HW implementation of the Ruby lazy. NOTE: to do, or may be not.



357
358
359
# File 'lib/HDLRuby/std/hruby_enum.rb', line 357

def hlazy(*args, &ruby_block)
  raise "hlazy is not supported yet."
end

#hmap(&ruby_block) ⇒ Object

Returns a HEnumerable containing the execution result of the given block on each element. If no block is given, return an HEnumerator.



101
102
103
104
105
106
107
108
109
110
# File 'lib/HDLRuby/std/hruby_enum.rb', line 101

def hmap(&ruby_block)
  # No block given? Generate a new wrapper enumerator for smap.
  if !ruby_block then
    return HEnumeratorWrapper.new(self,:hmap)
  end
  # A block given? Create the result HEnumerable (a Ruby array).
  res = []
  self.heach { |e| res << ruby_block.call(e) }
  return res
end

#hmax(n = nil, &ruby_block) ⇒ Object

HW implementation of the Ruby max.



362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
# File 'lib/HDLRuby/std/hruby_enum.rb', line 362

def hmax(n = nil, &ruby_block)
  unless n then
    n = 1
    scalar = true
  end
  if self.hsize < 1 or n < 1 then
    # Empty, no max.
    return 0
  end
  unless ruby_block then
    # The default comparator.
    ruby_block = proc { |a,b| a > b }
  end
  # The 2-value max unit.
  max2 = proc {|a,b| HDLRuby::High.top_user.mux(ruby_block.call(a,b),b,a) }
  # The single max hearch.
  m = self.hreduce(&max2)
  res = [m]
  if n > 1 then
    raise "hmax not supported for more than one max element."
  end
  if scalar then
    # Scalar result case.
    return m
  else
    # Array result case.
    return res
  end
end

#hmax_by(n = nil, &ruby_block) ⇒ Object

HW implementation of the Ruby max_by.



393
394
395
396
397
398
399
400
401
402
# File 'lib/HDLRuby/std/hruby_enum.rb', line 393

def hmax_by(n = nil, &ruby_block)
  # No block given? Generate a new wrapper enumerator for smax_by.
  if !ruby_block then
    return HEnumeratorWrapper.new(self,:hmax_by,n)
  end
  # A block is given, use smax with a proc that applies ruby_block
  # before comparing.
  # return hmax(n) { |a,b| ruby_block.call(a) <=> ruby_block.call(b) }
  return hmax(n) { |a,b| ruby_block.call(a) > ruby_block.call(b) }
end

#hmin(n = nil, &ruby_block) ⇒ Object

HW implementation of the Ruby min.



405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
# File 'lib/HDLRuby/std/hruby_enum.rb', line 405

def hmin(n = nil, &ruby_block)
  unless n then
    n = 1
    scalar = true
  end
  if self.hsize < 1 or n < 1 then
    # Empty, no min.
    return 0
  end
  if !ruby_block then
    # The default comparator.
    ruby_block = proc { |a,b| a > b }
  end
  # The 2-value max unit.
  min2 = proc {|a,b| HDLRuby::High.top_user.mux(ruby_block.call(a,b),a,b) }
  # The single max hearch.
  m = self.hreduce(&min2)
  res = [m]
  if n > 1 then
    raise "hmin not supported for more than one max element."
  end
  # # The other max hearch.
  # ar = self.to_a
  # sign = self.type.signed?
  # (n-1).times do
  #   # Exclude the previous max.
  #   ar = ar.hmap do |a| 
  #     if sign then
  #       HDLRuby::High.top_user.mux(a == m, a, HDLRuby::High.cur_system.send("_0#{"1" * (a.type.width-1)}"))
  #     else
  #       HDLRuby::High.top_user.mux(a == m, a, HDLRuby::High.cur_system.send("_1#{"1" * (a.type.width-1)}"))
  #     end
  #   end
  #   m = ar.reduce(&min2)
  #   res << m
  # end
  if scalar then
    # Scalar result case.
    return m
  else
    # Array result case.
    return res
  end
end

#hmin_by(n = nil, &ruby_block) ⇒ Object

HW implementation of the Ruby min_by.



451
452
453
454
455
456
457
458
459
460
# File 'lib/HDLRuby/std/hruby_enum.rb', line 451

def hmin_by(n = nil, &ruby_block)
  # No block given? Generate a new wrapper enumerator for smin_by.
  if !ruby_block then
    return HEnumeratorWrapper.new(self,:hmin_by,n)
  end
  # A block is given, use smin with a proc that applies ruby_block
  # before comparing.
  # return hmin(n) { |a,b| ruby_block.call(a) <=> ruby_block.call(b) }
  return hmin(n) { |a,b| ruby_block.call(a) > ruby_block.call(b) }
end

#hminmax(&ruby_block) ⇒ Object

HW implementation of the Ruby minmax.



463
464
465
466
467
468
469
470
471
# File 'lib/HDLRuby/std/hruby_enum.rb', line 463

def hminmax(&ruby_block)
  res = []
  # Computes the min.
  res[0] = self.hmin(&ruby_block)
  # Computes the max.
  res[1] = self.hmax(&ruby_block)
  # Return the result.
  return res
end

#hminmax_by(&ruby_block) ⇒ Object

HW implementation of the Ruby minmax_by.



474
475
476
477
478
479
480
481
482
# File 'lib/HDLRuby/std/hruby_enum.rb', line 474

def hminmax_by(&ruby_block)
  res = []
  # Computes the min.
  res[0] = self.hmin_by(&ruby_block)
  # Computes the max.
  res[1] = self.hmax_by(&ruby_block)
  # Return the result.
  return res
end

#hnone?(arg = nil, &ruby_block) ⇒ Boolean

Tell if none of the elements respects a given criterion given either as +arg+ or as block.

Returns:

  • (Boolean)


486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
# File 'lib/HDLRuby/std/hruby_enum.rb', line 486

def hnone?(arg = nil, &ruby_block)
  if self.hsize < 1 then
    # Empty, so always true.
    return 1
  end
  comp = []
  if arg then
    # Compare each element to arg in parallel.
    comp = self.hmap do |elem|
      elem == arg
    end
  elsif ruby_block then
    # Use the ruby block in parallel.
    comp = self.hmap(&ruby_block)
  else
    # Nothing to check.
    return 1
  end
  # Reduce the result.
  return comp.reduce(&:|) != 1
end

#hone?(arg = nil, &ruby_block) ⇒ Boolean

Tell if one and only one of the elements respects a given criterion given either as +arg+ or as block.

Returns:

  • (Boolean)


510
511
512
513
514
515
516
517
518
519
# File 'lib/HDLRuby/std/hruby_enum.rb', line 510

def hone?(arg = nil,&ruby_block)
  if self.hsize < 1 then
    # Empty, so always false.
    return 0
  end
  # Count the occurences.
  cnt = self.hcount(arg,&ruby_block)
  # Check if count is 1.
  return cnt == 1
end

#hpartition(*args, &ruby_block) ⇒ Object

HW implementation of the Ruby partition. NOTE: to do, or may be not.



523
524
525
# File 'lib/HDLRuby/std/hruby_enum.rb', line 523

def hpartition(*args,&ruby_block)
  raise "spartition is not supported yet."
end

#hreject(&ruby_block) ⇒ Object

HW implementatiob of the Ruby reject.



528
529
530
# File 'lib/HDLRuby/std/hruby_enum.rb', line 528

def hreject(&ruby_block)
  return hselect {|elem| ~ruby_block.call(elem) }
end

#hreverse_each(*args, &ruby_block) ⇒ Object

HW implementatiob of the Ruby reverse_each.



533
534
535
536
537
538
539
540
# File 'lib/HDLRuby/std/hruby_enum.rb', line 533

def hreverse_each(*args,&ruby_block)
  # No block given? Generate a new wrapper enumerator for 
  # sreverse_each.
  if !ruby_block then
    return HEnumeratorWrapper.new(self,:hreverse_each,*args)
  end
  return self.to_a.reverse_each(&ruby_block)
end

#hselect(&ruby_block) ⇒ Object

HW implementation of the Ruby select.



262
263
264
# File 'lib/HDLRuby/std/hruby_enum.rb', line 262

def hselect(&ruby_block)
  raise "hselect is not supported yet."
end

#hslice_after(pattern = nil, &ruby_block) ⇒ Object

HW implementation of the Ruby slice_after. NOTE: to do, or may be not.



544
545
546
# File 'lib/HDLRuby/std/hruby_enum.rb', line 544

def hslice_after(pattern = nil,&ruby_block)
  raise "hslice_after is not supported yet."
end

#hslice_before(*args, &ruby_block) ⇒ Object

HW implementation of the Ruby slice_before. NOTE: to do, or may be not.



550
551
552
# File 'lib/HDLRuby/std/hruby_enum.rb', line 550

def hslice_before(*args,&ruby_block)
  raise "hslice_before is not supported yet."
end

#hslice_when(*args, &ruby_block) ⇒ Object

HW implementation of the Ruby slice_when. NOTE: to do, or may be not.



556
557
558
# File 'lib/HDLRuby/std/hruby_enum.rb', line 556

def hslice_when(*args,&ruby_block)
  raise "hslice_before is not supported yet."
end

#hsort(dummy = self.type.base.max.as(self.type.base), &ruby_block) ⇒ Object

HW implementation of the Ruby sort using the bitonic sort method. NOTE: dummy is the dummy value used for filling the holes in the comparison network if the number of elements is not a power of 2.



599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
# File 'lib/HDLRuby/std/hruby_enum.rb', line 599

def hsort(dummy = self.type.base.max.as(self.type.base), &ruby_block)
  # The size to sort
  size = self.hsize
  # The type of the base elements
  typ = self.type.base
  if(size <= 1) then
    # Not enough elements: already sorted.
    return self
  end
  # The power of 2 size.
  size2 = 2 ** ((size-1).width)
  # Generate the comparator.
  unless ruby_block then
    # The default comparator.
    ruby_block = proc { |a,b| a > b }
  end
  # Create a namespace.
  base_block = ruby_block
  ruby_block = proc do |*args|
    HDLRuby::High.top_user.sub do
      base_block.call(*args)
    end
  end
  # Generate the compare and swap of two elements.
  compswap = proc do |a,b|
    if b then
      HDLRuby::High.top_user.mux(ruby_block.call(a,b), [ b, a] , [a, b])
    else
      [a]
    end
  end
  # Create the input stage of the sorter.
  stages = [self.hto_a + [dummy] * (size2-size) ]
  # Generate the bitonic sorter.
  k = 2
  while(k <= size2) do
    j = k / 2
    while(j > 0) do
      # puts "New stage"
      # Create the new intermediate stage.
      stage = size2.times.map {|i| typ.inner(HDLRuby.uniq_name) }
      stages << stage
      size2.times do |i|
        # Determin the swapcomp positions.
        l = i ^ j
        # puts "size2=#{size2} i=#{i} j=#{j} l=#{l} k=#{k}"
        if l > i then
          if i & k == 0 then
            # puts "swap #{i} and #{l}"
            [stages[-1][l],stages[-1][i]] <=
              compswap.(stages[-2][i],stages[-2][l])
          else
            # puts "antiswap #{i} and #{l}"
            [stages[-1][i],stages[-1][l]] <=
              compswap.(stages[-2][i],stages[-2][l])
          end
        end
      end
      j /= 2
    end
    k *= 2
  end
  # puts "Done"
  return stages[-1][0..(size-1)]
end

#hsort_by(dummy = self.type.base.max.as(self.type.base), &ruby_block) ⇒ Object

HW implementation of the Ruby sort. NOTE: dummy is the dummy value used for filling the holes in the comparison network if the number of elements is not a power of 2.



668
669
670
671
672
673
674
675
676
677
# File 'lib/HDLRuby/std/hruby_enum.rb', line 668

def hsort_by(dummy = self.type.base.max.as(self.type.base),
             &ruby_block)
  # No block given? Generate a new wrapper enumerator for smin_by.
  if !ruby_block then
    return HEnumeratorWrapper.new(self,:hsort_by,n)
  end
  # A block is given, use smin with a proc that applies ruby_block
  # before comparing.
  return hsort(dummy) {|a,b| ruby_block.call(a) > ruby_block.call(b) }
end

#hsum(initial_value = nil, &ruby_block) ⇒ Object

HW implementation of the Ruby sum.



680
681
682
683
684
685
686
687
688
689
690
# File 'lib/HDLRuby/std/hruby_enum.rb', line 680

def hsum(initial_value = nil,&ruby_block)
  aux = self
  # Apply the ruby block of each element if any.
  aux = aux.hmap(&ruby_block) if ruby_block
  # Do the sum.
  if initial_value then
    return aux.hinject(initial_value,&:+)
  else
    return aux.hinject(&:+)
  end
end

#htake(n) ⇒ Object

The HW implementation of the Ruby take.



693
694
695
# File 'lib/HDLRuby/std/hruby_enum.rb', line 693

def htake(n)
  return self[0..n-1]
end

#htake_while(&ruby_block) ⇒ Object

The HW implementation of the Ruby take_while.



698
699
700
# File 'lib/HDLRuby/std/hruby_enum.rb', line 698

def htake_while(&ruby_block)
  raise "htake_while is not supported yet."
end

#htally(h = nil) ⇒ Object

HW implementation of the Ruby tally. NOTE: to do, or may be not.



704
705
706
# File 'lib/HDLRuby/std/hruby_enum.rb', line 704

def htally(h = nil)
  raise "htally is not supported yet."
end

#hto_aObject

HW implementation of the Ruby to_a.

def hto_a return self.heach.to_a end



255
256
257
258
259
# File 'lib/HDLRuby/std/hruby_enum.rb', line 255

def hto_a
  res = []
  self.heach { |e| res << e }
  return res
end

#hto_h(h = nil) ⇒ Object

HW implementation of the Ruby to_h. NOTE: to do, or may be not.



710
711
712
# File 'lib/HDLRuby/std/hruby_enum.rb', line 710

def hto_h(h = nil)
  raise "hto_h is not supported yet."
end

#huniq(&ruby_block) ⇒ Object

HW implementation of the Ruby uniq.



715
716
717
# File 'lib/HDLRuby/std/hruby_enum.rb', line 715

def huniq(&ruby_block)
  raise "huniq is not supported yet."
end

#hzip(obj, &ruby_block) ⇒ Object

HW implementation of the Ruby zip. NOTE: for now szip is deactivated untile tuples are properly handled by HDLRuby.



722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
# File 'lib/HDLRuby/std/hruby_enum.rb', line 722

def hzip(obj,&ruby_block)
  size = self.hsize
  ar = obj.hto_a
  if ar.size > 0 then
    typ = ar[0].type
  else
    typ = self.type.base
  end
  # Fills the obj array with 0 until its size match self's.
  ar << 0.to_expr.as(typ) while ar.size < size
  if ruby_block then
    # There is a block to apply.
    return self.hto_a.zip(ar,&ruby_block)
  else
    # There is no block to apply generate an two level array.
    return self.hto_a.zip(ar)
  end
end