HDLRuby 2.3.0 → 2.3.5

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.
@@ -1946,7 +1946,9 @@ module HDLRuby::Low
1946
1946
  # Generates the C text for reference as left value to a signal.
1947
1947
  # +level+ is the hierarchical level of the object.
1948
1948
  def to_c_signal(level = 0)
1949
- return to_c(level,true)
1949
+ # return to_c(level,true)
1950
+ return "make_ref_rangeS(#{self.ref.to_c_signal(level)}," +
1951
+ "value2integer(#{self.range.first.to_c(level)}),value2integer(#{self.range.last.to_c(level)}))"
1950
1952
  end
1951
1953
  end
1952
1954
 
@@ -294,6 +294,8 @@ module HDLRuby::Low
294
294
  # Is there a type to match?
295
295
  if type then
296
296
  # Yes, update the concat to the type.
297
+ # Get the real type in case of typedef.
298
+ type = type.def while type.is_a?(TypeDef)
297
299
  # Is it an array type?
298
300
  if type.is_a?(TypeVector) then
299
301
  # Yes, update the concat without subcasting.
@@ -13,9 +13,9 @@ module HDLRuby
13
13
  @@absoluteCounter = -1 # The absolute name counter.
14
14
 
15
15
  # Generates an absolute uniq name.
16
- def self.uniq_name
16
+ def self.uniq_name(base = "")
17
17
  @@absoluteCounter += 1
18
- name = ":#{@@absoluteCounter}"
18
+ name = base.to_s + ":#{@@absoluteCounter}"
19
19
  if Symbol.all_symbols.find {|symbol| symbol.to_s == name } then
20
20
  # The symbol exists, try again.
21
21
  return self.uniq_name
@@ -612,14 +612,18 @@ extern Value read_range(Value value, long long first, long long last,
612
612
  * @param src the source value
613
613
  * @param first the first index of the range
614
614
  * @param last the last index of the range
615
+ * @param base the type of the elements
615
616
  * @param dst the destination value
616
617
  * @return dst */
617
- extern Value write_range(Value src, long long first, long long last, Value dst);
618
+ extern Value write_range(Value src, long long first, long long last,
619
+ Type base, Value dst);
618
620
 
619
621
  /** Writes to a range within a value but without overwrite with Z.
620
622
  * @param src the source value
621
623
  * @param first the first index of the range
622
624
  * @param last the last index of the range
625
+ * @param base the type of the elements
623
626
  * @param dst the destination value
624
627
  * @return dst */
625
- extern Value write_range_no_z(Value src, long long first, long long last, Value dst);
628
+ extern Value write_range_no_z(Value src, long long first, long long last,
629
+ Type base, Value dst);
@@ -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+
@@ -332,13 +342,21 @@ module HDLRuby::High::Std
332
342
  # building a channel.
333
343
  attr_reader :namespace
334
344
 
345
+ # The read port if any.
346
+ attr_reader :read_port
347
+
348
+ # The write port if any.
349
+ attr_reader :write_port
350
+
335
351
  ## Creates a new channel instance with +name+ built from +ruby_block+.
336
352
  def initialize(name,&ruby_block)
337
353
  # Check and set the name of the channel.
338
354
  @name = name.to_sym
355
+ # puts "my name is #{self.name}"
339
356
  # Generate a name for the scope containing the signals of
340
357
  # the channel.
341
- @scope_name = HDLRuby.uniq_name
358
+ # @scope_name = HDLRuby.uniq_name
359
+ @scope_name = HDLRuby.uniq_name(name)
342
360
 
343
361
  # # Sets the scope.
344
362
  # @scope = HDLRuby::High.cur_scope
@@ -346,6 +364,10 @@ module HDLRuby::High::Std
346
364
  # Keep access to self.
347
365
  obj = self
348
366
 
367
+ # At first there no read nor write port.
368
+ @read_port = nil
369
+ @write_port = nil
370
+
349
371
  # The reader input ports by name.
350
372
  @reader_inputs = {}
351
373
  # The reader output ports by name.
@@ -367,11 +389,6 @@ module HDLRuby::High::Std
367
389
  # The accesser inout ports by name.
368
390
  @accesser_inouts = {}
369
391
 
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
392
  # The branch channels
376
393
  @branches = {}
377
394
 
@@ -427,6 +444,11 @@ module HDLRuby::High::Std
427
444
  HDLRuby::High.space_reg(@name) { obj }
428
445
  end
429
446
 
447
+ # Get the parent system.
448
+ def parent_system
449
+ return self.scope.parent_system
450
+ end
451
+
430
452
  # The methods for defining the channel
431
453
 
432
454
  # For the channel itself
@@ -606,11 +628,18 @@ module HDLRuby::High::Std
606
628
  @writer_inouts.values
607
629
  end
608
630
 
631
+ ## Tells if the channel support inout port.
632
+ def inout?
633
+ return @accesser_inputs.any? || @accesser_outputs.any? ||
634
+ @accesser_inouts.any?
635
+ end
636
+
609
637
  # Defines a branch in the channel named +name+ built executing
610
638
  # +ruby_block+.
611
639
  # Alternatively, a ready channel instance can be passed as argument
612
640
  # as +channelI+.
613
641
  def brancher(name,channelI = nil,&ruby_block)
642
+ # puts "self.name=#{self.name} and name=#{name}"
614
643
  # Ensure name is a symbol.
615
644
  name = name.to_s unless name.respond_to?(:to_sym)
616
645
  name = name.to_sym
@@ -620,9 +649,9 @@ module HDLRuby::High::Std
620
649
  @branches[name] = channelI
621
650
  return self
622
651
  end
623
- # No, create the branch.
624
- # channelI = HDLRuby::High.channel_instance(name, &ruby_block)
652
+ # Now, create the branch.
625
653
  channelI = HDLRuby::High::Std.channel_instance(name, &ruby_block)
654
+ # channelI = HDLRuby::High::Std.channel_instance("#{self.name}::#{name}", &ruby_block)
626
655
  @branches[name] = channelI
627
656
  return self
628
657
  end
@@ -644,54 +673,83 @@ module HDLRuby::High::Std
644
673
 
645
674
  # Reader, writer and accesser side.
646
675
 
647
- ## Declares the ports for the reader and assigned them to +name+.
648
- def input(name)
676
+ ## Declares the reader port as and assigned them to +name+.
677
+ def input(name = nil)
649
678
  # Ensure name is a symbol.
679
+ name = HDLRuby.uniq_name unless name
650
680
  name = name.to_sym
681
+ # Ensure the port is not already existing.
682
+ if @read_port then
683
+ raise "Read port already declared for channel instance: " +
684
+ self.name
685
+ end
686
+
651
687
  # Access the ports
652
- loc_inputs = @reader_inputs
653
- loc_outputs = @reader_outputs
654
- loc_inouts = @reader_inouts
688
+ # loc_inputs = @reader_inputs
689
+ # loc_outputs = @reader_outputs
690
+ # loc_inouts = @reader_inouts
691
+ loc_inputs = @reader_inputs.merge(@accesser_inputs)
692
+ loc_outputs = @reader_outputs.merge(@accesser_outputs)
693
+ loc_inouts = @reader_inouts.merge(@accesser_inouts)
694
+ locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
655
695
  # The generated port with corresponding channel port pairs.
656
696
  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)]
697
+ if HDLRuby::High.cur_system == self.parent_system then
698
+ # Port in same system as the channel case.
699
+ # Add them to the current system.
700
+ HDLRuby::High.cur_system.open do
701
+ locs.each do |name,sig|
702
+ port_pairs << [sig, sig.type.inner(name)]
703
+ end
663
704
  end
664
- # The outputs
665
- loc_outputs.each do |name,sig|
666
- port_pairs << [sig, sig.type.output(name)]
705
+ obj = self
706
+ # Make the inner connection
707
+ port_pairs.each do |sig, port|
708
+ sig.parent.open do
709
+ port.to_ref <= sig
710
+ end
667
711
  end
668
- # The inouts
669
- loc_inouts.each do |name,sig|
670
- port_pairs << [sig, sig.type.inout(name)]
712
+ else
713
+ # Port in different system as the channel case.
714
+ # Add them to the current system.
715
+ HDLRuby::High.cur_system.open do
716
+ # The inputs
717
+ loc_inputs.each do |name,sig|
718
+ # puts "name=#{name} sig.name=#{sig.name}"
719
+ port_pairs << [sig, sig.type.input(name)]
720
+ end
721
+ # The outputs
722
+ loc_outputs.each do |name,sig|
723
+ port_pairs << [sig, sig.type.output(name)]
724
+ end
725
+ # The inouts
726
+ loc_inouts.each do |name,sig|
727
+ port_pairs << [sig, sig.type.inout(name)]
728
+ end
671
729
  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
730
+ obj = self
731
+ # Make the connection of the instance.
732
+ HDLRuby::High.cur_system.on_instance do |inst|
733
+ obj.scope.open do
734
+ port_pairs.each do |sig, port|
735
+ RefObject.new(inst,port.to_ref) <= sig
736
+ end
679
737
  end
680
738
  end
681
739
  end
682
740
 
683
741
  # Fill the reader namespace with the access to the reader signals.
684
- @reader_inputs.each do |name,sig|
742
+ loc_inputs.each do |name,sig|
685
743
  @reader_namespace.add_method(sig.name) do
686
744
  HDLRuby::High.top_user.send(name)
687
745
  end
688
746
  end
689
- @reader_outputs.each do |name,sig|
747
+ loc_outputs.each do |name,sig|
690
748
  @reader_namespace.add_method(sig.name) do
691
749
  HDLRuby::High.top_user.send(name)
692
750
  end
693
751
  end
694
- @reader_inouts.each do |name,sig|
752
+ loc_inouts.each do |name,sig|
695
753
  @reader_namespace.add_method(sig.name) do
696
754
  HDLRuby::High.top_user.send(name)
697
755
  end
@@ -701,56 +759,88 @@ module HDLRuby::High::Std
701
759
  # NOTE: for now, simply associate the channel to name.
702
760
  chp = ChannelPortR.new(@reader_namespace,@reader_proc,@input_reseter_proc)
703
761
  HDLRuby::High.space_reg(name) { chp }
762
+ # Save the port in the channe to avoid conflicting declaration.
763
+ @read_port = chp
704
764
  return chp
705
765
  end
706
766
 
707
767
  ## Declares the ports for the writer and assigned them to +name+.
708
- def output(name)
768
+ def output(name = nil)
709
769
  # Ensure name is a symbol.
770
+ name = HDLRuby.uniq_name unless name
710
771
  name = name.to_sym
772
+ # Ensure the port is not already existing.
773
+ if @write_port then
774
+ raise "Write port already declared for channel instance: " +
775
+ self.name
776
+ end
711
777
  # Access the ports
712
- loc_inputs = @writer_inputs
713
- loc_outputs = @writer_outputs
714
- loc_inouts = @writer_inouts
778
+ # loc_inputs = @writer_inputs
779
+ # loc_outputs = @writer_outputs
780
+ # loc_inouts = @writer_inouts
781
+ loc_inputs = @writer_inputs.merge(@accesser_inputs)
782
+ loc_outputs = @writer_outputs.merge(@accesser_outputs)
783
+ loc_inouts = @writer_inouts.merge(@accesser_inouts)
784
+ locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
715
785
  # The generated port with corresponding channel port pairs.
716
786
  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)]
787
+ # puts "cur_system=#{HDLRuby::High.cur_system} self.parent_system=#{self.parent_system}"
788
+ if HDLRuby::High.cur_system == self.parent_system then
789
+ # puts "Inner found!"
790
+ # Port in same system as the channel case.
791
+ # Add them to the current system.
792
+ HDLRuby::High.cur_system.open do
793
+ locs.each do |name,sig|
794
+ port_pairs << [sig, sig.type.inner(name)]
795
+ end
722
796
  end
723
- # The outputs
724
- loc_outputs.each do |name,sig|
725
- port_pairs << [sig, sig.type.output(name)]
797
+ obj = self
798
+ # Make the inner connection
799
+ port_pairs.each do |sig, port|
800
+ sig.parent.open do
801
+ port.to_ref <= sig
802
+ end
726
803
  end
727
- # The inouts
728
- loc_inouts.each do |name,sig|
729
- port_pairs << [sig, sig.type.inout(name)]
804
+ else
805
+ # Portds in different system as the channel's case.
806
+ # Add them to the current system.
807
+ HDLRuby::High.cur_system.open do
808
+ # The inputs
809
+ loc_inputs.each do |name,sig|
810
+ port_pairs << [sig, sig.type.input(name)]
811
+ end
812
+ # The outputs
813
+ loc_outputs.each do |name,sig|
814
+ port_pairs << [sig, sig.type.output(name)]
815
+ end
816
+ # The inouts
817
+ loc_inouts.each do |name,sig|
818
+ port_pairs << [sig, sig.type.inout(name)]
819
+ end
730
820
  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
821
+ obj = self
822
+ # Make the connection of the instance.
823
+ HDLRuby::High.cur_system.on_instance do |inst|
824
+ obj.scope.open do
825
+ port_pairs.each do |sig, port|
826
+ RefObject.new(inst,port.to_ref) <= sig
827
+ end
738
828
  end
739
829
  end
740
830
  end
741
831
 
742
832
  # Fill the writer namespace with the access to the writer signals.
743
- @writer_inputs.each do |name,sig|
833
+ loc_inputs.each do |name,sig|
744
834
  @writer_namespace.add_method(sig.name) do
745
835
  HDLRuby::High.top_user.send(name)
746
836
  end
747
837
  end
748
- @writer_outputs.each do |name,sig|
838
+ loc_outputs.each do |name,sig|
749
839
  @writer_namespace.add_method(sig.name) do
750
840
  HDLRuby::High.top_user.send(name)
751
841
  end
752
842
  end
753
- @writer_inouts.each do |name,sig|
843
+ loc_inouts.each do |name,sig|
754
844
  @writer_namespace.add_method(sig.name) do
755
845
  HDLRuby::High.top_user.send(name)
756
846
  end
@@ -760,73 +850,28 @@ module HDLRuby::High::Std
760
850
  # NOTE: for now, simply associate the channel to name.
761
851
  chp = ChannelPortW.new(@writer_namespace,@writer_proc,@output_reseter_proc)
762
852
  HDLRuby::High.space_reg(name) { chp }
853
+ # Save the port in the channe to avoid conflicting declaration.
854
+ @write_port = chp
763
855
  return chp
764
856
  end
765
857
 
766
- ## Declares the ports for the accesser and assigned them to +name+.
767
- def inout(name)
858
+
859
+ ## Declares the accesser port and assigned them to +name+.
860
+ def inout(name = nil)
768
861
  # Ensure name is a symbol.
862
+ name = HDLRuby.uniq_name unless name
769
863
  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
864
+ # Ensure the port is not already existing.
865
+ if @read_port then
866
+ raise "Read port already declared for channel instance: " +
867
+ self.name
799
868
  end
800
869
 
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
870
+ if @write_port then
871
+ raise "Write port already declared for channel instance: " +
872
+ self.name
806
873
  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
811
- 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
874
 
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
875
  # Access the ports
831
876
  loc_inputs = @accesser_inputs.merge(@reader_inputs).
832
877
  merge(@writer_inputs)
@@ -837,21 +882,51 @@ module HDLRuby::High::Std
837
882
  locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
838
883
  # The generated port with corresponding channel port pairs.
839
884
  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)]
885
+ if HDLRuby::High.cur_system == self.parent_system then
886
+ # Port in same system as the channel case.
887
+ # Add them to the current system.
888
+ HDLRuby::High.cur_system.open do
889
+ locs.each do |name,sig|
890
+ port_pairs << [sig, sig.type.inner(name)]
891
+ end
844
892
  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
893
+ obj = self
894
+ # Make the inner connection
895
+ port_pairs.each do |sig, port|
896
+ sig.parent.open do
897
+ port.to_ref <= sig
898
+ end
899
+ end
900
+ else
901
+ # Port in different system as the channel case.
902
+ # Add them to the current system.
903
+ HDLRuby::High.cur_system.open do
904
+ # The inputs
905
+ loc_inputs.each do |name,sig|
906
+ # puts "name=#{name} sig.name=#{sig.name}"
907
+ port_pairs << [sig, sig.type.input(name)]
908
+ end
909
+ # The outputs
910
+ loc_outputs.each do |name,sig|
911
+ port_pairs << [sig, sig.type.output(name)]
912
+ end
913
+ # The inouts
914
+ loc_inouts.each do |name,sig|
915
+ port_pairs << [sig, sig.type.inout(name)]
916
+ end
917
+ end
918
+ obj = self
919
+ # Make the connection of the instance.
920
+ HDLRuby::High.cur_system.on_instance do |inst|
921
+ obj.scope.open do
922
+ port_pairs.each do |sig, port|
923
+ RefObject.new(inst,port.to_ref) <= sig
924
+ end
925
+ end
851
926
  end
852
927
  end
853
928
 
854
- # Set ups the accesser's namespace
929
+ # Fill the reader namespace with the access to the reader signals.
855
930
  loc_inputs.each do |name,sig|
856
931
  @accesser_namespace.add_method(sig.name) do
857
932
  HDLRuby::High.top_user.send(name)
@@ -872,37 +947,121 @@ module HDLRuby::High::Std
872
947
  # NOTE: for now, simply associate the channel to name.
873
948
  chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc)
874
949
  HDLRuby::High.space_reg(name) { chp }
950
+ # Save the port in the channe to avoid conflicting declaration.
951
+ @read_port = chp
952
+ @write_port = chp
875
953
  return chp
876
954
  end
877
955
 
956
+ # ## Declares the ports for accessing the channel as an inner component
957
+ # # and assigned them to +name+.
958
+ # def inner(name)
959
+ # # Ensure name is a symbol.
960
+ # name = name.to_sym
961
+ # # Access the ports
962
+ # loc_inputs = @accesser_inputs.merge(@reader_inputs).
963
+ # merge(@writer_inputs)
964
+ # loc_outputs = @accesser_outputs.merge(@reader_outputs).
965
+ # merge(@writer_outputs)
966
+ # loc_inouts = @accesser_inouts.merge(@reader_inouts).
967
+ # merge(@writer_inouts)
968
+ # locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
969
+ # # The generated port with corresponding channel port pairs.
970
+ # port_pairs = []
971
+ # # Add them to the current system.
972
+ # HDLRuby::High.cur_system.open do
973
+ # locs.each do |name,sig|
974
+ # port_pairs << [sig, sig.type.inner(name)]
975
+ # end
976
+ # end
977
+ # obj = self
978
+ # # Make the inner connection
979
+ # port_pairs.each do |sig, port|
980
+ # sig.parent.open do
981
+ # port.to_ref <= sig
982
+ # end
983
+ # end
984
+
985
+ # # Set ups the accesser's namespace
986
+ # loc_inputs.each do |name,sig|
987
+ # @accesser_namespace.add_method(sig.name) do
988
+ # HDLRuby::High.top_user.send(name)
989
+ # end
990
+ # end
991
+ # loc_outputs.each do |name,sig|
992
+ # @accesser_namespace.add_method(sig.name) do
993
+ # HDLRuby::High.top_user.send(name)
994
+ # end
995
+ # end
996
+ # loc_inouts.each do |name,sig|
997
+ # @accesser_namespace.add_method(sig.name) do
998
+ # HDLRuby::High.top_user.send(name)
999
+ # end
1000
+ # end
1001
+
1002
+ # # Give access to the ports through name.
1003
+ # # NOTE: for now, simply associate the channel to name.
1004
+ # chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc)
1005
+ # HDLRuby::High.space_reg(name) { chp }
1006
+ # return chp
1007
+ # end
1008
+
1009
+
878
1010
 
879
1011
  ## Performs a read on the channel using +args+ and +ruby_block+
880
1012
  # as arguments.
1013
+ # NOTE:
1014
+ # * Will generate a port if not present.
1015
+ # * Will generate an error if a read is tempted while the read
1016
+ # port has been declared within another system.
881
1017
  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)
1018
+ # Is there a port to read?
1019
+ unless self.read_port then
1020
+ # No, generate a new one.
1021
+ # Is it possible to be inout?
1022
+ if self.inout? then
1023
+ # Yes, create an inout port.
1024
+ self.inout(HDLRuby.uniq_name)
1025
+ else
1026
+ # No, create an input port.
1027
+ self.input(HDLRuby.uniq_name)
1028
+ end
889
1029
  end
890
- HDLRuby::High.space_pop
1030
+ # Ensure the read port is within current system.
1031
+ unless self.read_port.scope.system != HDLRuby::High.cur_system then
1032
+ raise "Cannot read from a port external of current system for channel " + self.name
1033
+ end
1034
+ # Performs the read.
1035
+ self.read_port.read(*args,&ruby_block)
891
1036
  end
892
1037
 
893
1038
  ## Performs a write on the channel using +args+ and +ruby_block+
894
1039
  # as arguments.
1040
+ # NOTE:
1041
+ # * Will generate a port if not present.
1042
+ # * Will generate an error if a read is tempted while the read
1043
+ # port has been declared within another system.
895
1044
  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)
1045
+ # Is there a port to write?
1046
+ unless self.write_port then
1047
+ # No, generate a new one.
1048
+ # Is it possible to be inout?
1049
+ if self.inout? then
1050
+ # Yes, create an inout port.
1051
+ self.inout(HDLRuby.uniq_name)
1052
+ else
1053
+ # No, create an output port.
1054
+ self.output(HDLRuby.uniq_name)
1055
+ end
903
1056
  end
904
- HDLRuby::High.space_pop
1057
+ # Ensure the write port is within current system.
1058
+ unless self.write_port.scope.system != HDLRuby::High.cur_system then
1059
+ raise "Cannot write from a port external of current system for channel " + self.name
1060
+ end
1061
+ # Performs the write.
1062
+ self.write_port.write(*args,&ruby_block)
905
1063
  end
1064
+
906
1065
 
907
1066
  ## Performs a reset on the channel using +args+ and +ruby_block+
908
1067
  # as arguments.
@@ -925,6 +1084,8 @@ module HDLRuby::High::Std
925
1084
  # Create a new object wrapper for +obj+.
926
1085
  def initialize(obj)
927
1086
  @obj = obj
1087
+
1088
+ @scope = HDLRuby::High.cur_scope
928
1089
  end
929
1090
 
930
1091
  # Port read with arguments +args+ executing +ruby_block+ in