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.
- checksums.yaml +4 -4
- data/README.md +19 -13
- data/lib/HDLRuby/hdr_samples/with_channel.rb +49 -8
- data/lib/HDLRuby/hdr_samples/with_linear.rb +44 -24
- data/lib/HDLRuby/hdrcc.rb +7 -11
- data/lib/HDLRuby/hruby_check.rb +25 -1
- data/lib/HDLRuby/hruby_high.rb +6 -3
- data/lib/HDLRuby/hruby_low.rb +19 -0
- data/lib/HDLRuby/hruby_low2c.rb +3 -1
- data/lib/HDLRuby/hruby_low_fix_types.rb +2 -0
- data/lib/HDLRuby/hruby_tools.rb +2 -2
- data/lib/HDLRuby/sim/hruby_sim.h +6 -2
- data/lib/HDLRuby/sim/hruby_sim_calc.c +25 -12
- data/lib/HDLRuby/sim/hruby_sim_core.c +12 -4
- data/lib/HDLRuby/std/channel.rb +308 -147
- data/lib/HDLRuby/std/fixpoint.rb +42 -40
- data/lib/HDLRuby/std/memory.rb +3 -3
- data/lib/HDLRuby/version.rb +1 -1
- metadata +2 -2
data/lib/HDLRuby/hruby_low2c.rb
CHANGED
@@ -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.
|
data/lib/HDLRuby/hruby_tools.rb
CHANGED
@@ -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
|
data/lib/HDLRuby/sim/hruby_sim.h
CHANGED
@@ -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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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
|
}
|
data/lib/HDLRuby/std/channel.rb
CHANGED
@@ -45,8 +45,10 @@ module HDLRuby::High::Std
|
|
45
45
|
# Generates the channels.
|
46
46
|
channelI = nil
|
47
47
|
args.each do |nameI|
|
48
|
-
|
49
|
-
|
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
|
-
#
|
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
|
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
|
-
|
658
|
-
|
659
|
-
#
|
660
|
-
|
661
|
-
|
662
|
-
|
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
|
-
|
665
|
-
|
666
|
-
|
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
|
-
|
669
|
-
|
670
|
-
|
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
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
#
|
718
|
-
HDLRuby::High.cur_system.
|
719
|
-
#
|
720
|
-
|
721
|
-
|
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
|
-
|
724
|
-
|
725
|
-
|
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
|
-
|
728
|
-
|
729
|
-
|
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
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
767
|
-
|
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
|
-
#
|
771
|
-
|
772
|
-
|
773
|
-
|
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
|
-
|
802
|
-
|
803
|
-
|
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
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
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
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
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
|
-
#
|
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
|
-
#
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
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
|
-
|
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
|
-
#
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
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
|
-
|
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
|