HDLRuby 2.3.2 → 2.3.7

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.
@@ -1354,10 +1354,11 @@ Value read_range_bitstring(Value src, long long first, long long last,
1354
1354
  * @param src the source value
1355
1355
  * @param first the first index of the range
1356
1356
  * @param last the last index of the range
1357
+ * @param base the type of the elements
1357
1358
  * @param dst the destination value
1358
1359
  * @return dst */
1359
1360
  Value write_range_bitstring(Value src, long long first, long long last,
1360
- Value dst) {
1361
+ Type base, Value dst) {
1361
1362
  unsigned long long i;
1362
1363
  /* Ensure first is the smaller. */
1363
1364
  if (first > last) {
@@ -1370,7 +1371,8 @@ Value write_range_bitstring(Value src, long long first, long long last,
1370
1371
  unsigned long long src_width = type_width(src->type);
1371
1372
  unsigned long long dst_width = type_width(dst->type);
1372
1373
  /* scale the range according to the base type. */
1373
- unsigned long long bw = dst->type->base;
1374
+ // unsigned long long bw = dst->type->base;
1375
+ unsigned long long bw = type_width(base);
1374
1376
  first *= bw;
1375
1377
  last *= bw;
1376
1378
  last += bw-1;
@@ -1391,10 +1393,11 @@ Value write_range_bitstring(Value src, long long first, long long last,
1391
1393
  * @param src the source value
1392
1394
  * @param first the first index of the range
1393
1395
  * @param last the last index of the range
1396
+ * @param base the type of the elements
1394
1397
  * @param dst the destination value
1395
1398
  * @return dst */
1396
1399
  Value write_range_bitstring_no_z(Value src, long long first, long long last,
1397
- Value dst) {
1400
+ Type base, Value dst) {
1398
1401
  unsigned long long i;
1399
1402
  /* Ensure first is the smaller. */
1400
1403
  if (first > last) {
@@ -1406,7 +1409,8 @@ Value write_range_bitstring_no_z(Value src, long long first, long long last,
1406
1409
  unsigned long long src_width = type_width(src->type);
1407
1410
  unsigned long long dst_width = type_width(dst->type);
1408
1411
  /* scale the range according to the base type. */
1409
- unsigned long long bw = dst->type->base;
1412
+ // unsigned long long bw = dst->type->base;
1413
+ unsigned long long bw = type_width(base);
1410
1414
  first *= bw;
1411
1415
  last *= bw;
1412
1416
  /* Access the source and destination bitstring data. */
@@ -1864,10 +1868,11 @@ Value read_range_numeric(Value value, long long first, long long last,
1864
1868
  * @param src the source value
1865
1869
  * @param first the first index of the range
1866
1870
  * @param last the last index of the range
1871
+ * @param base the type of the elements
1867
1872
  * @param dst the destination value
1868
1873
  * @return dst */
1869
1874
  Value write_range_numeric(Value src, long long first, long long last,
1870
- Value dst) {
1875
+ Type base, Value dst) {
1871
1876
  // printf("write_range_numeric\n");
1872
1877
  /* Ensure first is the smaller. */
1873
1878
  if (first > last) {
@@ -1879,7 +1884,8 @@ Value write_range_numeric(Value src, long long first, long long last,
1879
1884
  unsigned long long src_width = type_width(src->type);
1880
1885
  unsigned long long dst_width = type_width(dst->type);
1881
1886
  /* scale the range according to the base type of the destination. */
1882
- unsigned long long bw = dst->type->base;
1887
+ // unsigned long long bw = dst->type->base;
1888
+ unsigned long long bw = type_width(base);
1883
1889
  // printf("src_width=%llu dst_wdith=%llu bw=%llu\n",src_width,dst_width,bw);
1884
1890
  first *= bw;
1885
1891
  last *= bw;
@@ -2691,14 +2697,17 @@ Value read_range(Value value, long long first, long long last, Type base,
2691
2697
  * @param src the source value
2692
2698
  * @param first the first index of the range
2693
2699
  * @param last the last index of the range
2700
+ * @param base the type of the elements
2694
2701
  * @param dst the destination value
2695
2702
  * @return dst */
2696
- Value write_range(Value src, long long first, long long last, Value dst) {
2703
+ Value write_range(Value src, long long first, long long last, Type base,
2704
+ Value dst) {
2697
2705
  // printf("write_range\n");
2698
2706
  /* Is the value numeric? */
2699
2707
  if ((src->numeric) && (dst->numeric)) {
2700
2708
  /* Yes, do a numeric range read. */
2701
- return write_range_numeric(src,first,last,dst);
2709
+ // return write_range_numeric(src,first,last,dst);
2710
+ return write_range_numeric(src,first,last,base,dst);
2702
2711
  } else {
2703
2712
  /* No, do a bitstring range read. */
2704
2713
  if (dst->numeric) {
@@ -2708,7 +2717,8 @@ Value write_range(Value src, long long first, long long last, Value dst) {
2708
2717
  /* Need to convert the source to a bitstring. */
2709
2718
  src = set_bitstring_value(src,get_value());
2710
2719
  }
2711
- return write_range_bitstring(src,first,last,dst);
2720
+ // return write_range_bitstring(src,first,last,dst);
2721
+ return write_range_bitstring(src,first,last,base,dst);
2712
2722
  }
2713
2723
  }
2714
2724
 
@@ -2717,14 +2727,16 @@ Value write_range(Value src, long long first, long long last, Value dst) {
2717
2727
  * @param src the source value
2718
2728
  * @param first the first index of the range
2719
2729
  * @param last the last index of the range
2730
+ * @param base the type of the elements
2720
2731
  * @param dst the destination value
2721
2732
  * @return dst */
2722
- Value write_range_no_z(Value src, long long first, long long last, Value dst) {
2733
+ Value write_range_no_z(Value src, long long first, long long last, Type base,
2734
+ Value dst) {
2723
2735
  // printf("write_range_no_z\n");
2724
2736
  /* Is the value numeric? */
2725
2737
  if ((src->numeric) && (dst->numeric)) {
2726
2738
  /* Yes, do a numeric range read. */
2727
- return write_range_numeric(src,first,last,dst);
2739
+ return write_range_numeric(src,first,last,base,dst);
2728
2740
  } else {
2729
2741
  /* No, do a bitstring range read. */
2730
2742
  if (dst->numeric) {
@@ -2734,7 +2746,8 @@ Value write_range_no_z(Value src, long long first, long long last, Value dst) {
2734
2746
  /* Need to convert the source to a bitstring. */
2735
2747
  src = set_bitstring_value(src,get_value());
2736
2748
  }
2737
- return write_range_bitstring_no_z(src,first,last,dst);
2749
+ // return write_range_bitstring_no_z(src,first,last,dst);
2750
+ return write_range_bitstring_no_z(src,first,last,base,dst);
2738
2751
  }
2739
2752
  }
2740
2753
 
@@ -365,6 +365,7 @@ void* behavior_run(void* arg) {
365
365
  * @note create a thread per timed behavior. */
366
366
  void hruby_sim_start_timed_behaviors() {
367
367
  int i;
368
+ pthread_mutex_lock(&hruby_sim_mutex);
368
369
  /* Sets the end flags to 0. */
369
370
  sim_end_flag = 0;
370
371
  /* Create and start the threads. */
@@ -375,6 +376,7 @@ void hruby_sim_start_timed_behaviors() {
375
376
  pthread_create(&timed_behaviors[i]->thread,NULL,
376
377
  &behavior_run,timed_behaviors[i]);
377
378
  }
379
+ pthread_mutex_unlock(&hruby_sim_mutex);
378
380
  }
379
381
 
380
382
  /** Ends waiting all the threads properly terminates. */
@@ -497,12 +499,18 @@ void transmit_to_signal_range(Value value, RefRangeS ref) {
497
499
  SignalI signal = ref.signal;
498
500
  unsigned long long first = ref.first;
499
501
  unsigned long long last = ref.last;
502
+ /* The base type is stored here to avoid allocating a new type each time.
503
+ * It have an arbitrary base size a single element. */
504
+ static TypeS baseT = { 1, 1 };
505
+ baseT.base = signal->f_value->type->base;
500
506
  // printf("Tansmit to signal range: %s(%p) [%lld:%lld]\n",signal->name,signal,first,last);
501
507
  /* Can transmit, copy the content. */
502
508
  if (signal->fading)
503
- signal->f_value = write_range(value,first,last,signal->f_value);
509
+ signal->f_value = write_range(value,first,last,&baseT,
510
+ signal->f_value);
504
511
  else
505
- signal->f_value = write_range_no_z(value,first,last,signal->f_value);
512
+ signal->f_value = write_range_no_z(value,first,last,&baseT,
513
+ signal->f_value);
506
514
  /* And touch the signal. */
507
515
  touch_signal(signal);
508
516
  }
@@ -551,9 +559,9 @@ void transmit_to_signal_range_seq(Value value, RefRangeS ref) {
551
559
  // printf("Tansmit to signal range: %s(%p)\n",signal->name,signal);
552
560
  /* Can transmit, copy the content. */
553
561
  if (signal->fading)
554
- write_range(value,first,last,signal->f_value);
562
+ write_range(value,first,last,signal->f_value->type,signal->f_value);
555
563
  else
556
- write_range_no_z(value,first,last,signal->f_value);
564
+ write_range_no_z(value,first,last,signal->f_value->type,signal->f_value);
557
565
  /* And touch the signal. */
558
566
  touch_signal_seq(signal);
559
567
  }
@@ -45,8 +45,10 @@ module HDLRuby::High::Std
45
45
  # Generates the channels.
46
46
  channelI = nil
47
47
  args.each do |nameI|
48
- channelI = ChannelI.new(name,&@ruby_block)
49
- HDLRuby::High.space_reg(nameI) { channelI }
48
+ # puts "nameI=#{nameI}"
49
+ channelI = ChannelI.new(nameI,&@ruby_block)
50
+ # Already registered!
51
+ # HDLRuby::High.space_reg(nameI) { channelI }
50
52
  end
51
53
  channelI
52
54
  end
@@ -96,6 +98,9 @@ module HDLRuby::High::Std
96
98
  def wrap(*args)
97
99
  return ChannelPortB.new(self,*args)
98
100
  end
101
+
102
+ # The scope the port has been declared in.
103
+ attr_reader :scope
99
104
  end
100
105
 
101
106
 
@@ -113,6 +118,7 @@ module HDLRuby::High::Std
113
118
  @namespace = namespace
114
119
  @reader_proc = reader_proc.to_proc
115
120
  @rester_proc = reseter_proc ? reseter_proc.to_proc : proc {}
121
+ @scope = HDLRuby::High.cur_scope
116
122
  end
117
123
 
118
124
  ## Performs a read on the channel using +args+ and +ruby_block+
@@ -157,6 +163,7 @@ module HDLRuby::High::Std
157
163
  @namespace = namespace
158
164
  @writer_proc = writer_proc.to_proc
159
165
  @reseter_proc = reseter_proc ? reseter_proc.to_proc : proc {}
166
+ @scope = HDLRuby::High.cur_scope
160
167
  end
161
168
 
162
169
  ## Performs a write on the channel using +args+ and +ruby_block+
@@ -206,6 +213,7 @@ module HDLRuby::High::Std
206
213
  @reader_proc = reader_proc ? reader_proc.to_proc : proc { }
207
214
  @writer_proc = writer_proc ? writer_proc.to_proc : proc { }
208
215
  @reseter_proc = reseter_proc ? reseter_proc.to_proc : proc {}
216
+ @scope = HDLRuby::High.cur_scope
209
217
  end
210
218
 
211
219
  ## Performs a read on the channel using +args+ and +ruby_block+
@@ -281,6 +289,8 @@ module HDLRuby::High::Std
281
289
  @args_write = args.clone
282
290
  @args_access = args.clone
283
291
  end
292
+
293
+ @scope = @port.scope
284
294
  end
285
295
 
286
296
  ## Performs a read on the channel using +args+ and +ruby_block+
@@ -315,6 +325,86 @@ module HDLRuby::High::Std
315
325
  end
316
326
 
317
327
 
328
+ ##
329
+ # Module giving the methods for accessing a channel instance.
330
+ module HchannelI
331
+ ## Performs a read on the channel using +args+ and +ruby_block+
332
+ # as arguments.
333
+ # NOTE:
334
+ # * Will generate a port if not present.
335
+ # * Will generate an error if a read is tempted while the read
336
+ # port has been declared within another system.
337
+ def read(*args,&ruby_block)
338
+ # Is there a port to read?
339
+ unless self.read_port then
340
+ # No, generate a new one.
341
+ # Is it possible to be inout?
342
+ if self.inout? then
343
+ # Yes, create an inout port.
344
+ self.inout(HDLRuby.uniq_name)
345
+ else
346
+ # No, create an input port.
347
+ self.input(HDLRuby.uniq_name)
348
+ end
349
+ end
350
+ # Ensure the read port is within current system.
351
+ unless self.read_port.scope.system != HDLRuby::High.cur_system then
352
+ raise "Cannot read from a port external of current system for channel " + self.name
353
+ end
354
+ # Performs the read.
355
+ self.read_port.read(*args,&ruby_block)
356
+ end
357
+
358
+ ## Performs a write on the channel using +args+ and +ruby_block+
359
+ # as arguments.
360
+ # NOTE:
361
+ # * Will generate a port if not present.
362
+ # * Will generate an error if a read is tempted while the read
363
+ # port has been declared within another system.
364
+ def write(*args,&ruby_block)
365
+ # Is there a port to write?
366
+ unless self.write_port then
367
+ # No, generate a new one.
368
+ # Is it possible to be inout?
369
+ if self.inout? then
370
+ # Yes, create an inout port.
371
+ self.inout(HDLRuby.uniq_name)
372
+ else
373
+ # No, create an output port.
374
+ self.output(HDLRuby.uniq_name)
375
+ end
376
+ end
377
+ # Ensure the write port is within current system.
378
+ unless self.write_port.scope.system != HDLRuby::High.cur_system then
379
+ raise "Cannot write from a port external of current system for channel " + self.name
380
+ end
381
+ # Performs the write.
382
+ self.write_port.write(*args,&ruby_block)
383
+ end
384
+
385
+
386
+ ## Performs a reset on the channel using +args+ and +ruby_block+
387
+ # as arguments.
388
+ def reset(*args,&ruby_block)
389
+ # Gain access to the writer as local variable.
390
+ reseter_proc = @inout_reseter_proc
391
+ # # The context is the one of the writer.
392
+ # Execute the code generating the writer in context.
393
+ HDLRuby::High.space_push(@namespace)
394
+ HDLRuby::High.cur_block.open do
395
+ instance_exec(ruby_block,*args,&reseter_proc)
396
+ end
397
+ HDLRuby::High.space_pop
398
+ end
399
+
400
+
401
+ # Wrap with +args+ arguments.
402
+ def wrap(*args)
403
+ return ChannelB.new(self,*args)
404
+ end
405
+ end
406
+
407
+
318
408
 
319
409
  ##
320
410
  # Describes a high-level channel instance.
@@ -332,13 +422,21 @@ module HDLRuby::High::Std
332
422
  # building a channel.
333
423
  attr_reader :namespace
334
424
 
425
+ # The read port if any.
426
+ attr_reader :read_port
427
+
428
+ # The write port if any.
429
+ attr_reader :write_port
430
+
335
431
  ## Creates a new channel instance with +name+ built from +ruby_block+.
336
432
  def initialize(name,&ruby_block)
337
433
  # Check and set the name of the channel.
338
434
  @name = name.to_sym
435
+ # puts "my name is #{self.name}"
339
436
  # Generate a name for the scope containing the signals of
340
437
  # the channel.
341
- @scope_name = HDLRuby.uniq_name
438
+ # @scope_name = HDLRuby.uniq_name
439
+ @scope_name = HDLRuby.uniq_name(name)
342
440
 
343
441
  # # Sets the scope.
344
442
  # @scope = HDLRuby::High.cur_scope
@@ -346,6 +444,10 @@ module HDLRuby::High::Std
346
444
  # Keep access to self.
347
445
  obj = self
348
446
 
447
+ # At first there no read nor write port.
448
+ @read_port = nil
449
+ @write_port = nil
450
+
349
451
  # The reader input ports by name.
350
452
  @reader_inputs = {}
351
453
  # The reader output ports by name.
@@ -367,11 +469,6 @@ module HDLRuby::High::Std
367
469
  # The accesser inout ports by name.
368
470
  @accesser_inouts = {}
369
471
 
370
- # # The default reset procedures (reseters), by default do nothing.
371
- # @input_reseter_proc = proc {}
372
- # @output_reseter_proc = proc {}
373
- # @inout_reseter_proc = proc {}
374
-
375
472
  # The branch channels
376
473
  @branches = {}
377
474
 
@@ -427,6 +524,11 @@ module HDLRuby::High::Std
427
524
  HDLRuby::High.space_reg(@name) { obj }
428
525
  end
429
526
 
527
+ # Get the parent system.
528
+ def parent_system
529
+ return self.scope.parent_system
530
+ end
531
+
430
532
  # The methods for defining the channel
431
533
 
432
534
  # For the channel itself
@@ -606,11 +708,18 @@ module HDLRuby::High::Std
606
708
  @writer_inouts.values
607
709
  end
608
710
 
711
+ ## Tells if the channel support inout port.
712
+ def inout?
713
+ return @accesser_inputs.any? || @accesser_outputs.any? ||
714
+ @accesser_inouts.any?
715
+ end
716
+
609
717
  # Defines a branch in the channel named +name+ built executing
610
718
  # +ruby_block+.
611
719
  # Alternatively, a ready channel instance can be passed as argument
612
720
  # as +channelI+.
613
721
  def brancher(name,channelI = nil,&ruby_block)
722
+ # puts "self.name=#{self.name} and name=#{name}"
614
723
  # Ensure name is a symbol.
615
724
  name = name.to_s unless name.respond_to?(:to_sym)
616
725
  name = name.to_sym
@@ -620,9 +729,9 @@ module HDLRuby::High::Std
620
729
  @branches[name] = channelI
621
730
  return self
622
731
  end
623
- # No, create the branch.
624
- # channelI = HDLRuby::High.channel_instance(name, &ruby_block)
732
+ # Now, create the branch.
625
733
  channelI = HDLRuby::High::Std.channel_instance(name, &ruby_block)
734
+ # channelI = HDLRuby::High::Std.channel_instance("#{self.name}::#{name}", &ruby_block)
626
735
  @branches[name] = channelI
627
736
  return self
628
737
  end
@@ -644,54 +753,83 @@ module HDLRuby::High::Std
644
753
 
645
754
  # Reader, writer and accesser side.
646
755
 
647
- ## Declares the ports for the reader and assigned them to +name+.
648
- def input(name)
756
+ ## Declares the reader port as and assigned them to +name+.
757
+ def input(name = nil)
649
758
  # Ensure name is a symbol.
759
+ name = HDLRuby.uniq_name unless name
650
760
  name = name.to_sym
761
+ # Ensure the port is not already existing.
762
+ if @read_port then
763
+ raise "Read port already declared for channel instance: " +
764
+ self.name
765
+ end
766
+
651
767
  # Access the ports
652
- loc_inputs = @reader_inputs
653
- loc_outputs = @reader_outputs
654
- loc_inouts = @reader_inouts
768
+ # loc_inputs = @reader_inputs
769
+ # loc_outputs = @reader_outputs
770
+ # loc_inouts = @reader_inouts
771
+ loc_inputs = @reader_inputs.merge(@accesser_inputs)
772
+ loc_outputs = @reader_outputs.merge(@accesser_outputs)
773
+ loc_inouts = @reader_inouts.merge(@accesser_inouts)
774
+ locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
655
775
  # The generated port with corresponding channel port pairs.
656
776
  port_pairs = []
657
- # Add them to the current system.
658
- HDLRuby::High.cur_system.open do
659
- # The inputs
660
- loc_inputs.each do |name,sig|
661
- # puts "name=#{name} sig.name=#{sig.name}"
662
- port_pairs << [sig, sig.type.input(name)]
777
+ if HDLRuby::High.cur_system == self.parent_system then
778
+ # Port in same system as the channel case.
779
+ # Add them to the current system.
780
+ HDLRuby::High.cur_system.open do
781
+ locs.each do |name,sig|
782
+ port_pairs << [sig, sig.type.inner(name)]
783
+ end
663
784
  end
664
- # The outputs
665
- loc_outputs.each do |name,sig|
666
- port_pairs << [sig, sig.type.output(name)]
785
+ obj = self
786
+ # Make the inner connection
787
+ port_pairs.each do |sig, port|
788
+ sig.parent.open do
789
+ port.to_ref <= sig
790
+ end
667
791
  end
668
- # The inouts
669
- loc_inouts.each do |name,sig|
670
- port_pairs << [sig, sig.type.inout(name)]
792
+ else
793
+ # Port in different system as the channel case.
794
+ # Add them to the current system.
795
+ HDLRuby::High.cur_system.open do
796
+ # The inputs
797
+ loc_inputs.each do |name,sig|
798
+ # puts "name=#{name} sig.name=#{sig.name}"
799
+ port_pairs << [sig, sig.type.input(name)]
800
+ end
801
+ # The outputs
802
+ loc_outputs.each do |name,sig|
803
+ port_pairs << [sig, sig.type.output(name)]
804
+ end
805
+ # The inouts
806
+ loc_inouts.each do |name,sig|
807
+ port_pairs << [sig, sig.type.inout(name)]
808
+ end
671
809
  end
672
- end
673
- obj = self
674
- # Make the connection of the instance.
675
- HDLRuby::High.cur_system.on_instance do |inst|
676
- obj.scope.open do
677
- port_pairs.each do |sig, port|
678
- RefObject.new(inst,port.to_ref) <= sig
810
+ obj = self
811
+ # Make the connection of the instance.
812
+ HDLRuby::High.cur_system.on_instance do |inst|
813
+ obj.scope.open do
814
+ port_pairs.each do |sig, port|
815
+ RefObject.new(inst,port.to_ref) <= sig
816
+ end
679
817
  end
680
818
  end
681
819
  end
682
820
 
683
821
  # Fill the reader namespace with the access to the reader signals.
684
- @reader_inputs.each do |name,sig|
822
+ loc_inputs.each do |name,sig|
685
823
  @reader_namespace.add_method(sig.name) do
686
824
  HDLRuby::High.top_user.send(name)
687
825
  end
688
826
  end
689
- @reader_outputs.each do |name,sig|
827
+ loc_outputs.each do |name,sig|
690
828
  @reader_namespace.add_method(sig.name) do
691
829
  HDLRuby::High.top_user.send(name)
692
830
  end
693
831
  end
694
- @reader_inouts.each do |name,sig|
832
+ loc_inouts.each do |name,sig|
695
833
  @reader_namespace.add_method(sig.name) do
696
834
  HDLRuby::High.top_user.send(name)
697
835
  end
@@ -701,56 +839,88 @@ module HDLRuby::High::Std
701
839
  # NOTE: for now, simply associate the channel to name.
702
840
  chp = ChannelPortR.new(@reader_namespace,@reader_proc,@input_reseter_proc)
703
841
  HDLRuby::High.space_reg(name) { chp }
842
+ # Save the port in the channe to avoid conflicting declaration.
843
+ @read_port = chp
704
844
  return chp
705
845
  end
706
846
 
707
847
  ## Declares the ports for the writer and assigned them to +name+.
708
- def output(name)
848
+ def output(name = nil)
709
849
  # Ensure name is a symbol.
850
+ name = HDLRuby.uniq_name unless name
710
851
  name = name.to_sym
852
+ # Ensure the port is not already existing.
853
+ if @write_port then
854
+ raise "Write port already declared for channel instance: " +
855
+ self.name
856
+ end
711
857
  # Access the ports
712
- loc_inputs = @writer_inputs
713
- loc_outputs = @writer_outputs
714
- loc_inouts = @writer_inouts
858
+ # loc_inputs = @writer_inputs
859
+ # loc_outputs = @writer_outputs
860
+ # loc_inouts = @writer_inouts
861
+ loc_inputs = @writer_inputs.merge(@accesser_inputs)
862
+ loc_outputs = @writer_outputs.merge(@accesser_outputs)
863
+ loc_inouts = @writer_inouts.merge(@accesser_inouts)
864
+ locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
715
865
  # The generated port with corresponding channel port pairs.
716
866
  port_pairs = []
717
- # Add them to the current system.
718
- HDLRuby::High.cur_system.open do
719
- # The inputs
720
- loc_inputs.each do |name,sig|
721
- port_pairs << [sig, sig.type.input(name)]
867
+ # puts "cur_system=#{HDLRuby::High.cur_system} self.parent_system=#{self.parent_system}"
868
+ if HDLRuby::High.cur_system == self.parent_system then
869
+ # puts "Inner found!"
870
+ # Port in same system as the channel case.
871
+ # Add them to the current system.
872
+ HDLRuby::High.cur_system.open do
873
+ locs.each do |name,sig|
874
+ port_pairs << [sig, sig.type.inner(name)]
875
+ end
722
876
  end
723
- # The outputs
724
- loc_outputs.each do |name,sig|
725
- port_pairs << [sig, sig.type.output(name)]
877
+ obj = self
878
+ # Make the inner connection
879
+ port_pairs.each do |sig, port|
880
+ sig.parent.open do
881
+ port.to_ref <= sig
882
+ end
726
883
  end
727
- # The inouts
728
- loc_inouts.each do |name,sig|
729
- port_pairs << [sig, sig.type.inout(name)]
884
+ else
885
+ # Portds in different system as the channel's case.
886
+ # Add them to the current system.
887
+ HDLRuby::High.cur_system.open do
888
+ # The inputs
889
+ loc_inputs.each do |name,sig|
890
+ port_pairs << [sig, sig.type.input(name)]
891
+ end
892
+ # The outputs
893
+ loc_outputs.each do |name,sig|
894
+ port_pairs << [sig, sig.type.output(name)]
895
+ end
896
+ # The inouts
897
+ loc_inouts.each do |name,sig|
898
+ port_pairs << [sig, sig.type.inout(name)]
899
+ end
730
900
  end
731
- end
732
- obj = self
733
- # Make the connection of the instance.
734
- HDLRuby::High.cur_system.on_instance do |inst|
735
- obj.scope.open do
736
- port_pairs.each do |sig, port|
737
- RefObject.new(inst,port.to_ref) <= sig
901
+ obj = self
902
+ # Make the connection of the instance.
903
+ HDLRuby::High.cur_system.on_instance do |inst|
904
+ obj.scope.open do
905
+ port_pairs.each do |sig, port|
906
+ RefObject.new(inst,port.to_ref) <= sig
907
+ end
738
908
  end
739
909
  end
740
910
  end
741
911
 
742
912
  # Fill the writer namespace with the access to the writer signals.
743
- @writer_inputs.each do |name,sig|
913
+ loc_inputs.each do |name,sig|
744
914
  @writer_namespace.add_method(sig.name) do
745
915
  HDLRuby::High.top_user.send(name)
746
916
  end
747
917
  end
748
- @writer_outputs.each do |name,sig|
918
+ loc_outputs.each do |name,sig|
749
919
  @writer_namespace.add_method(sig.name) do
750
920
  HDLRuby::High.top_user.send(name)
751
921
  end
752
922
  end
753
- @writer_inouts.each do |name,sig|
923
+ loc_inouts.each do |name,sig|
754
924
  @writer_namespace.add_method(sig.name) do
755
925
  HDLRuby::High.top_user.send(name)
756
926
  end
@@ -760,73 +930,28 @@ module HDLRuby::High::Std
760
930
  # NOTE: for now, simply associate the channel to name.
761
931
  chp = ChannelPortW.new(@writer_namespace,@writer_proc,@output_reseter_proc)
762
932
  HDLRuby::High.space_reg(name) { chp }
933
+ # Save the port in the channe to avoid conflicting declaration.
934
+ @write_port = chp
763
935
  return chp
764
936
  end
765
937
 
766
- ## Declares the ports for the accesser and assigned them to +name+.
767
- def inout(name)
938
+
939
+ ## Declares the accesser port and assigned them to +name+.
940
+ def inout(name = nil)
768
941
  # Ensure name is a symbol.
942
+ name = HDLRuby.uniq_name unless name
769
943
  name = name.to_sym
770
- # Access the ports
771
- loc_inputs = @accesser_inputs
772
- loc_outputs = @accesser_outputs
773
- loc_inouts = @accesser_inouts
774
- # The generated port with corresponding channel port pairs.
775
- port_pairs = []
776
- # Add them to the current system.
777
- HDLRuby::High.cur_system.open do
778
- # The inputs
779
- loc_inputs.each do |name,sig|
780
- port_pairs << [sig, sig.type.input(name)]
781
- end
782
- # The outputs
783
- loc_outputs.each do |name,sig|
784
- port_pairs << [sig, sig.type.output(name)]
785
- end
786
- # The inouts
787
- loc_inouts.each do |name,sig|
788
- port_pairs << [sig, sig.type.inout(name)]
789
- end
790
- end
791
- obj = self
792
- # Make the connection of the instance.
793
- HDLRuby::High.cur_system.on_instance do |inst|
794
- obj.scope.open do
795
- port_pairs.each do |sig, port|
796
- RefObject.new(inst,port.to_ref) <= sig
797
- end
798
- end
944
+ # Ensure the port is not already existing.
945
+ if @read_port then
946
+ raise "Read port already declared for channel instance: " +
947
+ self.name.to_s
799
948
  end
800
949
 
801
- # Set ups the accesser's namespace
802
- @accesser_inputs.each do |name,sig|
803
- @accesser_namespace.add_method(sig.name) do
804
- HDLRuby::High.top_user.send(name)
805
- end
806
- end
807
- @accesser_outputs.each do |name,sig|
808
- @accesser_namespace.add_method(sig.name) do
809
- HDLRuby::High.top_user.send(name)
810
- end
950
+ if @write_port then
951
+ raise "Write port already declared for channel instance: " +
952
+ self.name.to_s
811
953
  end
812
- @accesser_inouts.each do |name,sig|
813
- @accesser_namespace.add_method(sig.name) do
814
- HDLRuby::High.top_user.send(name)
815
- end
816
- end
817
-
818
- # Give access to the ports through name.
819
- # NOTE: for now, simply associate the channel to name.
820
- chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc)
821
- HDLRuby::High.space_reg(name) { chp }
822
- return chp
823
- end
824
954
 
825
- ## Declares the ports for accessing the channel as an inner component
826
- # and assigned them to +name+.
827
- def inner(name)
828
- # Ensure name is a symbol.
829
- name = name.to_sym
830
955
  # Access the ports
831
956
  loc_inputs = @accesser_inputs.merge(@reader_inputs).
832
957
  merge(@writer_inputs)
@@ -837,21 +962,51 @@ module HDLRuby::High::Std
837
962
  locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
838
963
  # The generated port with corresponding channel port pairs.
839
964
  port_pairs = []
840
- # Add them to the current system.
841
- HDLRuby::High.cur_system.open do
842
- locs.each do |name,sig|
843
- port_pairs << [sig, sig.type.inner(name)]
965
+ if HDLRuby::High.cur_system == self.parent_system then
966
+ # Port in same system as the channel case.
967
+ # Add them to the current system.
968
+ HDLRuby::High.cur_system.open do
969
+ locs.each do |name,sig|
970
+ port_pairs << [sig, sig.type.inner(name)]
971
+ end
844
972
  end
845
- end
846
- obj = self
847
- # Make the inner connection
848
- port_pairs.each do |sig, port|
849
- sig.parent.open do
850
- port.to_ref <= sig
973
+ obj = self
974
+ # Make the inner connection
975
+ port_pairs.each do |sig, port|
976
+ sig.parent.open do
977
+ port.to_ref <= sig
978
+ end
979
+ end
980
+ else
981
+ # Port in different system as the channel case.
982
+ # Add them to the current system.
983
+ HDLRuby::High.cur_system.open do
984
+ # The inputs
985
+ loc_inputs.each do |name,sig|
986
+ # puts "name=#{name} sig.name=#{sig.name}"
987
+ port_pairs << [sig, sig.type.input(name)]
988
+ end
989
+ # The outputs
990
+ loc_outputs.each do |name,sig|
991
+ port_pairs << [sig, sig.type.output(name)]
992
+ end
993
+ # The inouts
994
+ loc_inouts.each do |name,sig|
995
+ port_pairs << [sig, sig.type.inout(name)]
996
+ end
997
+ end
998
+ obj = self
999
+ # Make the connection of the instance.
1000
+ HDLRuby::High.cur_system.on_instance do |inst|
1001
+ obj.scope.open do
1002
+ port_pairs.each do |sig, port|
1003
+ RefObject.new(inst,port.to_ref) <= sig
1004
+ end
1005
+ end
851
1006
  end
852
1007
  end
853
1008
 
854
- # Set ups the accesser's namespace
1009
+ # Fill the reader namespace with the access to the reader signals.
855
1010
  loc_inputs.each do |name,sig|
856
1011
  @accesser_namespace.add_method(sig.name) do
857
1012
  HDLRuby::High.top_user.send(name)
@@ -872,51 +1027,297 @@ module HDLRuby::High::Std
872
1027
  # NOTE: for now, simply associate the channel to name.
873
1028
  chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc)
874
1029
  HDLRuby::High.space_reg(name) { chp }
1030
+ # Save the port in the channe to avoid conflicting declaration.
1031
+ @read_port = chp
1032
+ @write_port = chp
875
1033
  return chp
876
1034
  end
877
1035
 
1036
+ # ## Declares the ports for accessing the channel as an inner component
1037
+ # # and assigned them to +name+.
1038
+ # def inner(name)
1039
+ # # Ensure name is a symbol.
1040
+ # name = name.to_sym
1041
+ # # Access the ports
1042
+ # loc_inputs = @accesser_inputs.merge(@reader_inputs).
1043
+ # merge(@writer_inputs)
1044
+ # loc_outputs = @accesser_outputs.merge(@reader_outputs).
1045
+ # merge(@writer_outputs)
1046
+ # loc_inouts = @accesser_inouts.merge(@reader_inouts).
1047
+ # merge(@writer_inouts)
1048
+ # locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
1049
+ # # The generated port with corresponding channel port pairs.
1050
+ # port_pairs = []
1051
+ # # Add them to the current system.
1052
+ # HDLRuby::High.cur_system.open do
1053
+ # locs.each do |name,sig|
1054
+ # port_pairs << [sig, sig.type.inner(name)]
1055
+ # end
1056
+ # end
1057
+ # obj = self
1058
+ # # Make the inner connection
1059
+ # port_pairs.each do |sig, port|
1060
+ # sig.parent.open do
1061
+ # port.to_ref <= sig
1062
+ # end
1063
+ # end
1064
+
1065
+ # # Set ups the accesser's namespace
1066
+ # loc_inputs.each do |name,sig|
1067
+ # @accesser_namespace.add_method(sig.name) do
1068
+ # HDLRuby::High.top_user.send(name)
1069
+ # end
1070
+ # end
1071
+ # loc_outputs.each do |name,sig|
1072
+ # @accesser_namespace.add_method(sig.name) do
1073
+ # HDLRuby::High.top_user.send(name)
1074
+ # end
1075
+ # end
1076
+ # loc_inouts.each do |name,sig|
1077
+ # @accesser_namespace.add_method(sig.name) do
1078
+ # HDLRuby::High.top_user.send(name)
1079
+ # end
1080
+ # end
1081
+
1082
+ # # Give access to the ports through name.
1083
+ # # NOTE: for now, simply associate the channel to name.
1084
+ # chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc)
1085
+ # HDLRuby::High.space_reg(name) { chp }
1086
+ # return chp
1087
+ # end
1088
+
1089
+ # Standard channel access is given is HchannelI module.
1090
+ include HchannelI
1091
+
878
1092
 
879
- ## Performs a read on the channel using +args+ and +ruby_block+
880
- # as arguments.
881
- def read(*args,&ruby_block)
882
- # Gain access to the reader as local variable.
883
- reader_proc = @reader_proc
884
- # # The context is the one of the reader.
885
- # Execute the code generating the reader in context.
886
- HDLRuby::High.space_push(@namespace)
887
- HDLRuby::High.cur_block.open do
888
- instance_exec(ruby_block,*args,&reader_proc)
1093
+ # ## Performs a read on the channel using +args+ and +ruby_block+
1094
+ # # as arguments.
1095
+ # # NOTE:
1096
+ # # * Will generate a port if not present.
1097
+ # # * Will generate an error if a read is tempted while the read
1098
+ # # port has been declared within another system.
1099
+ # def read(*args,&ruby_block)
1100
+ # # Is there a port to read?
1101
+ # unless self.read_port then
1102
+ # # No, generate a new one.
1103
+ # # Is it possible to be inout?
1104
+ # if self.inout? then
1105
+ # # Yes, create an inout port.
1106
+ # self.inout(HDLRuby.uniq_name)
1107
+ # else
1108
+ # # No, create an input port.
1109
+ # self.input(HDLRuby.uniq_name)
1110
+ # end
1111
+ # end
1112
+ # # Ensure the read port is within current system.
1113
+ # unless self.read_port.scope.system != HDLRuby::High.cur_system then
1114
+ # raise "Cannot read from a port external of current system for channel " + self.name
1115
+ # end
1116
+ # # Performs the read.
1117
+ # self.read_port.read(*args,&ruby_block)
1118
+ # end
1119
+ #
1120
+ # ## Performs a write on the channel using +args+ and +ruby_block+
1121
+ # # as arguments.
1122
+ # # NOTE:
1123
+ # # * Will generate a port if not present.
1124
+ # # * Will generate an error if a read is tempted while the read
1125
+ # # port has been declared within another system.
1126
+ # def write(*args,&ruby_block)
1127
+ # # Is there a port to write?
1128
+ # unless self.write_port then
1129
+ # # No, generate a new one.
1130
+ # # Is it possible to be inout?
1131
+ # if self.inout? then
1132
+ # # Yes, create an inout port.
1133
+ # self.inout(HDLRuby.uniq_name)
1134
+ # else
1135
+ # # No, create an output port.
1136
+ # self.output(HDLRuby.uniq_name)
1137
+ # end
1138
+ # end
1139
+ # # Ensure the write port is within current system.
1140
+ # unless self.write_port.scope.system != HDLRuby::High.cur_system then
1141
+ # raise "Cannot write from a port external of current system for channel " + self.name
1142
+ # end
1143
+ # # Performs the write.
1144
+ # self.write_port.write(*args,&ruby_block)
1145
+ # end
1146
+ #
1147
+
1148
+ # ## Performs a reset on the channel using +args+ and +ruby_block+
1149
+ # # as arguments.
1150
+ # def reset(*args,&ruby_block)
1151
+ # # Gain access to the writer as local variable.
1152
+ # reseter_proc = @inout_reseter_proc
1153
+ # # # The context is the one of the writer.
1154
+ # # Execute the code generating the writer in context.
1155
+ # HDLRuby::High.space_push(@namespace)
1156
+ # HDLRuby::High.cur_block.open do
1157
+ # instance_exec(ruby_block,*args,&reseter_proc)
1158
+ # end
1159
+ # HDLRuby::High.space_pop
1160
+ # end
1161
+ end
1162
+
1163
+ # Describes channel instance wrapper (Box) for fixing arugments.
1164
+ class ChannelB
1165
+ include HDLRuby::High::Hmissing
1166
+ include HchannelI
1167
+
1168
+ # Create a new channel box over +channelI+ channel instance using
1169
+ # +args+ for fixing the arguments as follows:
1170
+ # It can also be three lists for seperate read, write and access
1171
+ # procedures using named arguments as:
1172
+ # read: <read arguments>, write: <write arguments>,
1173
+ # access: <access arguments>
1174
+ def initialize(channelI,*args)
1175
+ # Ensure port is a channel port.
1176
+ unless channelI.is_a?(ChannelI) || channel.is_a?(ChannelB)
1177
+ raise "Invalid class for a channel instance: #{ch.class}"
1178
+ end
1179
+ @channelI = channelI
1180
+ # Process the arguments.
1181
+ if args.size == 1 && args[0].is_a?(Hash) then
1182
+ # Read, write and access are separated.
1183
+ @args_read = args[0][:read]
1184
+ @args_write = args[0][:write]
1185
+ @args_access = args[0][:access]
1186
+ else
1187
+ @args_read = args
1188
+ @args_write = args.clone
1189
+ @args_access = args.clone
889
1190
  end
890
- HDLRuby::High.space_pop
891
1191
  end
1192
+
1193
+ # Delegates to the boxed channel instance.
1194
+
1195
+ # The name of the channel instance.
1196
+ def name
1197
+ return @channelI.name
1198
+ end
1199
+
1200
+ # The scope the channel has been created in.
1201
+ def scope
1202
+ return @channelI.scope
1203
+ end
1204
+
1205
+ # The namespace associated with the current execution when
1206
+ # building a channel.
1207
+ def namespace
1208
+ return @channelI.namespace
1209
+ end
1210
+
1211
+ # The read port if any.
1212
+ def read_port
1213
+ return @read_port
1214
+ end
1215
+
1216
+ # The write port if any.
1217
+ def write_port
1218
+ return @write_port
1219
+ end
1220
+
1221
+ # Methods used on the channel outside its definition.
892
1222
 
893
- ## Performs a write on the channel using +args+ and +ruby_block+
894
- # as arguments.
895
- def write(*args,&ruby_block)
896
- # Gain access to the writer as local variable.
897
- writer_proc = @writer_proc
898
- # # The context is the one of the writer.
899
- # Execute the code generating the writer in context.
900
- HDLRuby::High.space_push(@namespace)
901
- HDLRuby::High.cur_block.open do
902
- instance_exec(ruby_block,*args,&writer_proc)
1223
+ # Gets branch channel +name+.
1224
+ # NOTE:
1225
+ # * +name+ can be of any type on purpose.
1226
+ # * The wrapping arguments are not transmitted to the branch.
1227
+ def branch(name,*args)
1228
+ return @channelI.branch(name,*args)
1229
+ end
1230
+
1231
+ ## Tells if the channel support inout port.
1232
+ def inout?
1233
+ return @channelI.inout?
1234
+ end
1235
+
1236
+
1237
+ # Reader, writer and accesser side.
1238
+
1239
+ ## Declares the reader port as and assigned them to +name+.
1240
+ def input(name = nil)
1241
+ # Ensure name is a symbol.
1242
+ name = HDLRuby.uniq_name unless name
1243
+ name = name.to_sym
1244
+ # Ensure the port is not already existing.
1245
+ if @read_port then
1246
+ raise "Read port already declared for channel instance: " +
1247
+ self.name
903
1248
  end
904
- HDLRuby::High.space_pop
1249
+
1250
+ # Create a read port for the encaspulted channel.
1251
+ real_port = @channelI.read_port
1252
+ real_port = @channelI.input unless real_port
1253
+
1254
+ # Wrap it to a new port using.
1255
+ chp = real_port.wrap(read: @args_read)
1256
+
1257
+ HDLRuby::High.space_reg(name) { chp }
1258
+ # Save the port in the channe to avoid conflicting declaration.
1259
+ @read_port = chp
1260
+ return chp
905
1261
  end
906
1262
 
907
- ## Performs a reset on the channel using +args+ and +ruby_block+
908
- # as arguments.
909
- def reset(*args,&ruby_block)
910
- # Gain access to the writer as local variable.
911
- reseter_proc = @inout_reseter_proc
912
- # # The context is the one of the writer.
913
- # Execute the code generating the writer in context.
914
- HDLRuby::High.space_push(@namespace)
915
- HDLRuby::High.cur_block.open do
916
- instance_exec(ruby_block,*args,&reseter_proc)
1263
+ ## Declares the ports for the writer and assigned them to +name+.
1264
+ def output(name = nil)
1265
+ # Ensure name is a symbol.
1266
+ name = HDLRuby.uniq_name unless name
1267
+ name = name.to_sym
1268
+ # Ensure the port is not already existing.
1269
+ if @write_port then
1270
+ raise "Read port already declared for channel instance: " +
1271
+ self.name
917
1272
  end
918
- HDLRuby::High.space_pop
1273
+
1274
+ # Create a write port for the encaspulted channel.
1275
+ real_port = @channelI.write_port
1276
+ real_port = @channelI.output unless real_port
1277
+
1278
+ # Wrap it to a new port using.
1279
+ chp = real_port.wrap(write: @args_write)
1280
+
1281
+ HDLRuby::High.space_reg(name) { chp }
1282
+ # Save the port in the channe to avoid conflicting declaration.
1283
+ @write_port = chp
1284
+ return chp
919
1285
  end
1286
+
1287
+
1288
+ ## Declares the accesser port and assigned them to +name+.
1289
+ def inout(name = nil)
1290
+ # Ensure name is a symbol.
1291
+ name = HDLRuby.uniq_name unless name
1292
+ name = name.to_sym
1293
+ # Ensure the port is not already existing.
1294
+ if @read_port then
1295
+ raise "Read port already declared for channel instance: " +
1296
+ self.name
1297
+ end
1298
+ if @write_port then
1299
+ raise "Write port already declared for channel instance: " +
1300
+ self.name
1301
+ end
1302
+
1303
+ # Create a write port for the encaspulted channel.
1304
+ if @channelI.read_port == @channelI.write_port then
1305
+ real_port = @channelI.read_port
1306
+ real_port = @channelI.inout unless real_port
1307
+ else
1308
+ raise "Inout port not supported for channel #{@channelI}"
1309
+ end
1310
+
1311
+ # Wrap it to a new port using.
1312
+ chp = real_port.wrap(read: @args_read, write: @args_write)
1313
+
1314
+ HDLRuby::High.space_reg(name) { chp }
1315
+ # Save the port in the channe to avoid conflicting declaration.
1316
+ @write_port = chp
1317
+ @read_port = chp
1318
+ return chp
1319
+ end
1320
+
920
1321
  end
921
1322
 
922
1323
 
@@ -925,6 +1326,8 @@ module HDLRuby::High::Std
925
1326
  # Create a new object wrapper for +obj+.
926
1327
  def initialize(obj)
927
1328
  @obj = obj
1329
+
1330
+ @scope = HDLRuby::High.cur_scope
928
1331
  end
929
1332
 
930
1333
  # Port read with arguments +args+ executing +ruby_block+ in