HDLRuby 2.2.16 → 2.3.3
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 +33 -21
- data/lib/HDLRuby/hdr_samples/rom.rb +2 -2
- data/lib/HDLRuby/hdr_samples/ruby_fir_hw.rb +96 -0
- data/lib/HDLRuby/hdr_samples/with_channel.rb +49 -8
- data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +3 -2
- data/lib/HDLRuby/hdr_samples/with_linear.rb +48 -25
- data/lib/HDLRuby/hdr_samples/with_loop.rb +69 -0
- data/lib/HDLRuby/hdr_samples/with_memory.rb +13 -3
- data/lib/HDLRuby/hdrcc.rb +8 -12
- data/lib/HDLRuby/hruby_check.rb +25 -1
- data/lib/HDLRuby/hruby_high.rb +6 -0
- data/lib/HDLRuby/hruby_low.rb +43 -9
- data/lib/HDLRuby/hruby_low2c.rb +9 -5
- data/lib/HDLRuby/hruby_low2high.rb +1 -1
- data/lib/HDLRuby/hruby_low2vhd.rb +63 -48
- data/lib/HDLRuby/hruby_low_fix_types.rb +6 -2
- data/lib/HDLRuby/hruby_low_resolve.rb +5 -3
- data/lib/HDLRuby/hruby_low_without_concat.rb +8 -4
- data/lib/HDLRuby/hruby_types.rb +82 -72
- data/lib/HDLRuby/hruby_verilog.rb +9 -1
- data/lib/HDLRuby/sim/hruby_sim.h +7 -0
- data/lib/HDLRuby/sim/hruby_sim_calc.c +83 -6
- data/lib/HDLRuby/sim/hruby_sim_core.c +2 -0
- data/lib/HDLRuby/std/channel.rb +336 -158
- data/lib/HDLRuby/std/fixpoint.rb +50 -39
- data/lib/HDLRuby/std/linear.rb +68 -0
- data/lib/HDLRuby/std/loop.rb +101 -0
- data/lib/HDLRuby/std/memory.rb +1002 -32
- data/lib/HDLRuby/std/task.rb +850 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +6 -2
@@ -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. */
|
data/lib/HDLRuby/std/channel.rb
CHANGED
@@ -81,20 +81,31 @@ module HDLRuby::High::Std
|
|
81
81
|
end
|
82
82
|
|
83
83
|
|
84
|
-
##
|
85
|
-
# Module for wrapping channel ports.
|
86
|
-
module ChannelPortWrapping
|
84
|
+
# ##
|
85
|
+
# # Module for wrapping channel ports.
|
86
|
+
# module ChannelPortWrapping
|
87
|
+
# # Wrap with +args+ arguments.
|
88
|
+
# def wrap(*args)
|
89
|
+
# return ChannelPortB.new(self,*args)
|
90
|
+
# end
|
91
|
+
# end
|
92
|
+
|
93
|
+
## Describes a channel port.
|
94
|
+
class ChannelPort
|
87
95
|
# Wrap with +args+ arguments.
|
88
96
|
def wrap(*args)
|
89
97
|
return ChannelPortB.new(self,*args)
|
90
98
|
end
|
99
|
+
|
100
|
+
# The scope the port has been declared in.
|
101
|
+
attr_reader :scope
|
91
102
|
end
|
92
103
|
|
93
104
|
|
94
105
|
##
|
95
106
|
# Describes a read port to a channel.
|
96
|
-
class ChannelPortR
|
97
|
-
include ChannelPortWrapping
|
107
|
+
class ChannelPortR < ChannelPort
|
108
|
+
# include ChannelPortWrapping
|
98
109
|
|
99
110
|
# Creates a new channel reader running in +namespace+ and
|
100
111
|
# reading using +reader_proc+ and reseting using +reseter_proc+.
|
@@ -105,6 +116,7 @@ module HDLRuby::High::Std
|
|
105
116
|
@namespace = namespace
|
106
117
|
@reader_proc = reader_proc.to_proc
|
107
118
|
@rester_proc = reseter_proc ? reseter_proc.to_proc : proc {}
|
119
|
+
@scope = HDLRuby::High.cur_scope
|
108
120
|
end
|
109
121
|
|
110
122
|
## Performs a read on the channel using +args+ and +ruby_block+
|
@@ -137,8 +149,8 @@ module HDLRuby::High::Std
|
|
137
149
|
|
138
150
|
##
|
139
151
|
# Describes a writer port to a channel.
|
140
|
-
class ChannelPortW
|
141
|
-
include ChannelPortWrapping
|
152
|
+
class ChannelPortW < ChannelPort
|
153
|
+
# include ChannelPortWrapping
|
142
154
|
|
143
155
|
# Creates a new channel writer running in +namespace+ and
|
144
156
|
# writing using +writer_proc+ and reseting using +reseter_proc+.
|
@@ -149,6 +161,7 @@ module HDLRuby::High::Std
|
|
149
161
|
@namespace = namespace
|
150
162
|
@writer_proc = writer_proc.to_proc
|
151
163
|
@reseter_proc = reseter_proc ? reseter_proc.to_proc : proc {}
|
164
|
+
@scope = HDLRuby::High.cur_scope
|
152
165
|
end
|
153
166
|
|
154
167
|
## Performs a write on the channel using +args+ and +ruby_block+
|
@@ -181,8 +194,8 @@ module HDLRuby::High::Std
|
|
181
194
|
|
182
195
|
##
|
183
196
|
# Describes an access port to a channel.
|
184
|
-
class ChannelPortA
|
185
|
-
include ChannelPortWrapping
|
197
|
+
class ChannelPortA < ChannelPort
|
198
|
+
# include ChannelPortWrapping
|
186
199
|
|
187
200
|
# Creates a new channel accesser running in +namespace+
|
188
201
|
# and reading using +reader_proc+, writing using +writer_proc+,
|
@@ -198,6 +211,7 @@ module HDLRuby::High::Std
|
|
198
211
|
@reader_proc = reader_proc ? reader_proc.to_proc : proc { }
|
199
212
|
@writer_proc = writer_proc ? writer_proc.to_proc : proc { }
|
200
213
|
@reseter_proc = reseter_proc ? reseter_proc.to_proc : proc {}
|
214
|
+
@scope = HDLRuby::High.cur_scope
|
201
215
|
end
|
202
216
|
|
203
217
|
## Performs a read on the channel using +args+ and +ruby_block+
|
@@ -243,8 +257,8 @@ module HDLRuby::High::Std
|
|
243
257
|
|
244
258
|
##
|
245
259
|
# Describes port wrapper (Box) for fixing arugments.
|
246
|
-
class ChannelPortB
|
247
|
-
include ChannelPortWrapping
|
260
|
+
class ChannelPortB < ChannelPort
|
261
|
+
# include ChannelPortWrapping
|
248
262
|
|
249
263
|
# Creates a new channel box over channel port +port+ fixing +args+
|
250
264
|
# as arguments.
|
@@ -273,6 +287,8 @@ module HDLRuby::High::Std
|
|
273
287
|
@args_write = args.clone
|
274
288
|
@args_access = args.clone
|
275
289
|
end
|
290
|
+
|
291
|
+
@scope = @port.scope
|
276
292
|
end
|
277
293
|
|
278
294
|
## Performs a read on the channel using +args+ and +ruby_block+
|
@@ -324,6 +340,12 @@ module HDLRuby::High::Std
|
|
324
340
|
# building a channel.
|
325
341
|
attr_reader :namespace
|
326
342
|
|
343
|
+
# The read port if any.
|
344
|
+
attr_reader :read_port
|
345
|
+
|
346
|
+
# The write port if any.
|
347
|
+
attr_reader :write_port
|
348
|
+
|
327
349
|
## Creates a new channel instance with +name+ built from +ruby_block+.
|
328
350
|
def initialize(name,&ruby_block)
|
329
351
|
# Check and set the name of the channel.
|
@@ -338,6 +360,10 @@ module HDLRuby::High::Std
|
|
338
360
|
# Keep access to self.
|
339
361
|
obj = self
|
340
362
|
|
363
|
+
# At first there no read nor write port.
|
364
|
+
@read_port = nil
|
365
|
+
@write_port = nil
|
366
|
+
|
341
367
|
# The reader input ports by name.
|
342
368
|
@reader_inputs = {}
|
343
369
|
# The reader output ports by name.
|
@@ -359,11 +385,6 @@ module HDLRuby::High::Std
|
|
359
385
|
# The accesser inout ports by name.
|
360
386
|
@accesser_inouts = {}
|
361
387
|
|
362
|
-
# # The default reset procedures (reseters), by default do nothing.
|
363
|
-
# @input_reseter_proc = proc {}
|
364
|
-
# @output_reseter_proc = proc {}
|
365
|
-
# @inout_reseter_proc = proc {}
|
366
|
-
|
367
388
|
# The branch channels
|
368
389
|
@branches = {}
|
369
390
|
|
@@ -419,6 +440,11 @@ module HDLRuby::High::Std
|
|
419
440
|
HDLRuby::High.space_reg(@name) { obj }
|
420
441
|
end
|
421
442
|
|
443
|
+
# Get the parent system.
|
444
|
+
def parent_system
|
445
|
+
return self.scope.parent_system
|
446
|
+
end
|
447
|
+
|
422
448
|
# The methods for defining the channel
|
423
449
|
|
424
450
|
# For the channel itself
|
@@ -598,15 +624,30 @@ module HDLRuby::High::Std
|
|
598
624
|
@writer_inouts.values
|
599
625
|
end
|
600
626
|
|
627
|
+
## Tells if the channel support inout port.
|
628
|
+
def inout?
|
629
|
+
return @accesser_inputs.any? || @accesser_outputs.any? ||
|
630
|
+
@accesser_inouts.any?
|
631
|
+
end
|
632
|
+
|
601
633
|
# Defines a branch in the channel named +name+ built executing
|
602
634
|
# +ruby_block+.
|
603
|
-
|
635
|
+
# Alternatively, a ready channel instance can be passed as argument
|
636
|
+
# as +channelI+.
|
637
|
+
def brancher(name,channelI = nil,&ruby_block)
|
604
638
|
# Ensure name is a symbol.
|
605
639
|
name = name.to_s unless name.respond_to?(:to_sym)
|
606
640
|
name = name.to_sym
|
607
|
-
#
|
608
|
-
channelI
|
641
|
+
# Is there a ready channel instance.
|
642
|
+
if channelI then
|
643
|
+
# Yes, use it directly.
|
644
|
+
@branches[name] = channelI
|
645
|
+
return self
|
646
|
+
end
|
647
|
+
# Now, create the branch.
|
648
|
+
channelI = HDLRuby::High::Std.channel_instance(name, &ruby_block)
|
609
649
|
@branches[name] = channelI
|
650
|
+
return self
|
610
651
|
end
|
611
652
|
|
612
653
|
|
@@ -619,60 +660,90 @@ module HDLRuby::High::Std
|
|
619
660
|
name = name.to_s unless name.respond_to?(:to_sym)
|
620
661
|
name = name.to_sym
|
621
662
|
# Get the branch.
|
663
|
+
channelI = @branches[name]
|
622
664
|
return @branches[name]
|
623
665
|
end
|
624
666
|
|
625
667
|
|
626
668
|
# Reader, writer and accesser side.
|
627
669
|
|
628
|
-
## Declares the
|
629
|
-
def input(name)
|
670
|
+
## Declares the reader port as and assigned them to +name+.
|
671
|
+
def input(name = nil)
|
630
672
|
# Ensure name is a symbol.
|
673
|
+
name = HDLRuby.uniq_name unless name
|
631
674
|
name = name.to_sym
|
675
|
+
# Ensure the port is not already existing.
|
676
|
+
if @read_port then
|
677
|
+
raise "Read port already declared for channel instance: " +
|
678
|
+
self.name
|
679
|
+
end
|
680
|
+
|
632
681
|
# Access the ports
|
633
|
-
loc_inputs = @reader_inputs
|
634
|
-
loc_outputs = @reader_outputs
|
635
|
-
loc_inouts = @reader_inouts
|
682
|
+
# loc_inputs = @reader_inputs
|
683
|
+
# loc_outputs = @reader_outputs
|
684
|
+
# loc_inouts = @reader_inouts
|
685
|
+
loc_inputs = @reader_inputs.merge(@accesser_inputs)
|
686
|
+
loc_outputs = @reader_outputs.merge(@accesser_outputs)
|
687
|
+
loc_inouts = @reader_inouts.merge(@accesser_inouts)
|
688
|
+
locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
|
636
689
|
# The generated port with corresponding channel port pairs.
|
637
690
|
port_pairs = []
|
638
|
-
|
639
|
-
|
640
|
-
#
|
641
|
-
|
642
|
-
|
643
|
-
|
691
|
+
if HDLRuby::High.cur_system == self.parent_system then
|
692
|
+
# Port in same system as the channel case.
|
693
|
+
# Add them to the current system.
|
694
|
+
HDLRuby::High.cur_system.open do
|
695
|
+
locs.each do |name,sig|
|
696
|
+
port_pairs << [sig, sig.type.inner(name)]
|
697
|
+
end
|
644
698
|
end
|
645
|
-
|
646
|
-
|
647
|
-
|
699
|
+
obj = self
|
700
|
+
# Make the inner connection
|
701
|
+
port_pairs.each do |sig, port|
|
702
|
+
sig.parent.open do
|
703
|
+
port.to_ref <= sig
|
704
|
+
end
|
648
705
|
end
|
649
|
-
|
650
|
-
|
651
|
-
|
706
|
+
else
|
707
|
+
# Port in different system as the channel case.
|
708
|
+
# Add them to the current system.
|
709
|
+
HDLRuby::High.cur_system.open do
|
710
|
+
# The inputs
|
711
|
+
loc_inputs.each do |name,sig|
|
712
|
+
# puts "name=#{name} sig.name=#{sig.name}"
|
713
|
+
port_pairs << [sig, sig.type.input(name)]
|
714
|
+
end
|
715
|
+
# The outputs
|
716
|
+
loc_outputs.each do |name,sig|
|
717
|
+
port_pairs << [sig, sig.type.output(name)]
|
718
|
+
end
|
719
|
+
# The inouts
|
720
|
+
loc_inouts.each do |name,sig|
|
721
|
+
port_pairs << [sig, sig.type.inout(name)]
|
722
|
+
end
|
652
723
|
end
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
724
|
+
obj = self
|
725
|
+
# Make the connection of the instance.
|
726
|
+
HDLRuby::High.cur_system.on_instance do |inst|
|
727
|
+
obj.scope.open do
|
728
|
+
port_pairs.each do |sig, port|
|
729
|
+
RefObject.new(inst,port.to_ref) <= sig
|
730
|
+
end
|
660
731
|
end
|
661
732
|
end
|
662
733
|
end
|
663
734
|
|
664
735
|
# Fill the reader namespace with the access to the reader signals.
|
665
|
-
|
736
|
+
loc_inputs.each do |name,sig|
|
666
737
|
@reader_namespace.add_method(sig.name) do
|
667
738
|
HDLRuby::High.top_user.send(name)
|
668
739
|
end
|
669
740
|
end
|
670
|
-
|
741
|
+
loc_outputs.each do |name,sig|
|
671
742
|
@reader_namespace.add_method(sig.name) do
|
672
743
|
HDLRuby::High.top_user.send(name)
|
673
744
|
end
|
674
745
|
end
|
675
|
-
|
746
|
+
loc_inouts.each do |name,sig|
|
676
747
|
@reader_namespace.add_method(sig.name) do
|
677
748
|
HDLRuby::High.top_user.send(name)
|
678
749
|
end
|
@@ -682,56 +753,88 @@ module HDLRuby::High::Std
|
|
682
753
|
# NOTE: for now, simply associate the channel to name.
|
683
754
|
chp = ChannelPortR.new(@reader_namespace,@reader_proc,@input_reseter_proc)
|
684
755
|
HDLRuby::High.space_reg(name) { chp }
|
756
|
+
# Save the port in the channe to avoid conflicting declaration.
|
757
|
+
@read_port = chp
|
685
758
|
return chp
|
686
759
|
end
|
687
760
|
|
688
761
|
## Declares the ports for the writer and assigned them to +name+.
|
689
|
-
def output(name)
|
762
|
+
def output(name = nil)
|
690
763
|
# Ensure name is a symbol.
|
764
|
+
name = HDLRuby.uniq_name unless name
|
691
765
|
name = name.to_sym
|
766
|
+
# Ensure the port is not already existing.
|
767
|
+
if @write_port then
|
768
|
+
raise "Write port already declared for channel instance: " +
|
769
|
+
self.name
|
770
|
+
end
|
692
771
|
# Access the ports
|
693
|
-
loc_inputs = @writer_inputs
|
694
|
-
loc_outputs = @writer_outputs
|
695
|
-
loc_inouts = @writer_inouts
|
772
|
+
# loc_inputs = @writer_inputs
|
773
|
+
# loc_outputs = @writer_outputs
|
774
|
+
# loc_inouts = @writer_inouts
|
775
|
+
loc_inputs = @writer_inputs.merge(@accesser_inputs)
|
776
|
+
loc_outputs = @writer_outputs.merge(@accesser_outputs)
|
777
|
+
loc_inouts = @writer_inouts.merge(@accesser_inouts)
|
778
|
+
locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
|
696
779
|
# The generated port with corresponding channel port pairs.
|
697
780
|
port_pairs = []
|
698
|
-
#
|
699
|
-
HDLRuby::High.cur_system.
|
700
|
-
#
|
701
|
-
|
702
|
-
|
781
|
+
# puts "cur_system=#{HDLRuby::High.cur_system} self.parent_system=#{self.parent_system}"
|
782
|
+
if HDLRuby::High.cur_system == self.parent_system then
|
783
|
+
# puts "Inner found!"
|
784
|
+
# Port in same system as the channel case.
|
785
|
+
# Add them to the current system.
|
786
|
+
HDLRuby::High.cur_system.open do
|
787
|
+
locs.each do |name,sig|
|
788
|
+
port_pairs << [sig, sig.type.inner(name)]
|
789
|
+
end
|
703
790
|
end
|
704
|
-
|
705
|
-
|
706
|
-
|
791
|
+
obj = self
|
792
|
+
# Make the inner connection
|
793
|
+
port_pairs.each do |sig, port|
|
794
|
+
sig.parent.open do
|
795
|
+
port.to_ref <= sig
|
796
|
+
end
|
707
797
|
end
|
708
|
-
|
709
|
-
|
710
|
-
|
798
|
+
else
|
799
|
+
# Portds in different system as the channel's case.
|
800
|
+
# Add them to the current system.
|
801
|
+
HDLRuby::High.cur_system.open do
|
802
|
+
# The inputs
|
803
|
+
loc_inputs.each do |name,sig|
|
804
|
+
port_pairs << [sig, sig.type.input(name)]
|
805
|
+
end
|
806
|
+
# The outputs
|
807
|
+
loc_outputs.each do |name,sig|
|
808
|
+
port_pairs << [sig, sig.type.output(name)]
|
809
|
+
end
|
810
|
+
# The inouts
|
811
|
+
loc_inouts.each do |name,sig|
|
812
|
+
port_pairs << [sig, sig.type.inout(name)]
|
813
|
+
end
|
711
814
|
end
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
815
|
+
obj = self
|
816
|
+
# Make the connection of the instance.
|
817
|
+
HDLRuby::High.cur_system.on_instance do |inst|
|
818
|
+
obj.scope.open do
|
819
|
+
port_pairs.each do |sig, port|
|
820
|
+
RefObject.new(inst,port.to_ref) <= sig
|
821
|
+
end
|
719
822
|
end
|
720
823
|
end
|
721
824
|
end
|
722
825
|
|
723
826
|
# Fill the writer namespace with the access to the writer signals.
|
724
|
-
|
827
|
+
loc_inputs.each do |name,sig|
|
725
828
|
@writer_namespace.add_method(sig.name) do
|
726
829
|
HDLRuby::High.top_user.send(name)
|
727
830
|
end
|
728
831
|
end
|
729
|
-
|
832
|
+
loc_outputs.each do |name,sig|
|
730
833
|
@writer_namespace.add_method(sig.name) do
|
731
834
|
HDLRuby::High.top_user.send(name)
|
732
835
|
end
|
733
836
|
end
|
734
|
-
|
837
|
+
loc_inouts.each do |name,sig|
|
735
838
|
@writer_namespace.add_method(sig.name) do
|
736
839
|
HDLRuby::High.top_user.send(name)
|
737
840
|
end
|
@@ -741,73 +844,28 @@ module HDLRuby::High::Std
|
|
741
844
|
# NOTE: for now, simply associate the channel to name.
|
742
845
|
chp = ChannelPortW.new(@writer_namespace,@writer_proc,@output_reseter_proc)
|
743
846
|
HDLRuby::High.space_reg(name) { chp }
|
847
|
+
# Save the port in the channe to avoid conflicting declaration.
|
848
|
+
@write_port = chp
|
744
849
|
return chp
|
745
850
|
end
|
746
851
|
|
747
|
-
|
748
|
-
|
852
|
+
|
853
|
+
## Declares the accesser port and assigned them to +name+.
|
854
|
+
def inout(name = nil)
|
749
855
|
# Ensure name is a symbol.
|
856
|
+
name = HDLRuby.uniq_name unless name
|
750
857
|
name = name.to_sym
|
751
|
-
#
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
# The generated port with corresponding channel port pairs.
|
756
|
-
port_pairs = []
|
757
|
-
# Add them to the current system.
|
758
|
-
HDLRuby::High.cur_system.open do
|
759
|
-
# The inputs
|
760
|
-
loc_inputs.each do |name,sig|
|
761
|
-
port_pairs << [sig, sig.type.input(name)]
|
762
|
-
end
|
763
|
-
# The outputs
|
764
|
-
loc_outputs.each do |name,sig|
|
765
|
-
port_pairs << [sig, sig.type.output(name)]
|
766
|
-
end
|
767
|
-
# The inouts
|
768
|
-
loc_inouts.each do |name,sig|
|
769
|
-
port_pairs << [sig, sig.type.inout(name)]
|
770
|
-
end
|
771
|
-
end
|
772
|
-
obj = self
|
773
|
-
# Make the connection of the instance.
|
774
|
-
HDLRuby::High.cur_system.on_instance do |inst|
|
775
|
-
obj.scope.open do
|
776
|
-
port_pairs.each do |sig, port|
|
777
|
-
RefObject.new(inst,port.to_ref) <= sig
|
778
|
-
end
|
779
|
-
end
|
858
|
+
# Ensure the port is not already existing.
|
859
|
+
if @read_port then
|
860
|
+
raise "Read port already declared for channel instance: " +
|
861
|
+
self.name
|
780
862
|
end
|
781
863
|
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
HDLRuby::High.top_user.send(name)
|
786
|
-
end
|
787
|
-
end
|
788
|
-
@accesser_outputs.each do |name,sig|
|
789
|
-
@accesser_namespace.add_method(sig.name) do
|
790
|
-
HDLRuby::High.top_user.send(name)
|
791
|
-
end
|
792
|
-
end
|
793
|
-
@accesser_inouts.each do |name,sig|
|
794
|
-
@accesser_namespace.add_method(sig.name) do
|
795
|
-
HDLRuby::High.top_user.send(name)
|
796
|
-
end
|
864
|
+
if @write_port then
|
865
|
+
raise "Write port already declared for channel instance: " +
|
866
|
+
self.name
|
797
867
|
end
|
798
868
|
|
799
|
-
# Give access to the ports through name.
|
800
|
-
# NOTE: for now, simply associate the channel to name.
|
801
|
-
chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc)
|
802
|
-
HDLRuby::High.space_reg(name) { chp }
|
803
|
-
return chp
|
804
|
-
end
|
805
|
-
|
806
|
-
## Declares the ports for accessing the channel as an inner component
|
807
|
-
# and assigned them to +name+.
|
808
|
-
def inner(name)
|
809
|
-
# Ensure name is a symbol.
|
810
|
-
name = name.to_sym
|
811
869
|
# Access the ports
|
812
870
|
loc_inputs = @accesser_inputs.merge(@reader_inputs).
|
813
871
|
merge(@writer_inputs)
|
@@ -818,21 +876,51 @@ module HDLRuby::High::Std
|
|
818
876
|
locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
|
819
877
|
# The generated port with corresponding channel port pairs.
|
820
878
|
port_pairs = []
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
879
|
+
if HDLRuby::High.cur_system == self.parent_system then
|
880
|
+
# Port in same system as the channel case.
|
881
|
+
# Add them to the current system.
|
882
|
+
HDLRuby::High.cur_system.open do
|
883
|
+
locs.each do |name,sig|
|
884
|
+
port_pairs << [sig, sig.type.inner(name)]
|
885
|
+
end
|
825
886
|
end
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
887
|
+
obj = self
|
888
|
+
# Make the inner connection
|
889
|
+
port_pairs.each do |sig, port|
|
890
|
+
sig.parent.open do
|
891
|
+
port.to_ref <= sig
|
892
|
+
end
|
893
|
+
end
|
894
|
+
else
|
895
|
+
# Port in different system as the channel case.
|
896
|
+
# Add them to the current system.
|
897
|
+
HDLRuby::High.cur_system.open do
|
898
|
+
# The inputs
|
899
|
+
loc_inputs.each do |name,sig|
|
900
|
+
# puts "name=#{name} sig.name=#{sig.name}"
|
901
|
+
port_pairs << [sig, sig.type.input(name)]
|
902
|
+
end
|
903
|
+
# The outputs
|
904
|
+
loc_outputs.each do |name,sig|
|
905
|
+
port_pairs << [sig, sig.type.output(name)]
|
906
|
+
end
|
907
|
+
# The inouts
|
908
|
+
loc_inouts.each do |name,sig|
|
909
|
+
port_pairs << [sig, sig.type.inout(name)]
|
910
|
+
end
|
911
|
+
end
|
912
|
+
obj = self
|
913
|
+
# Make the connection of the instance.
|
914
|
+
HDLRuby::High.cur_system.on_instance do |inst|
|
915
|
+
obj.scope.open do
|
916
|
+
port_pairs.each do |sig, port|
|
917
|
+
RefObject.new(inst,port.to_ref) <= sig
|
918
|
+
end
|
919
|
+
end
|
832
920
|
end
|
833
921
|
end
|
834
922
|
|
835
|
-
#
|
923
|
+
# Fill the reader namespace with the access to the reader signals.
|
836
924
|
loc_inputs.each do |name,sig|
|
837
925
|
@accesser_namespace.add_method(sig.name) do
|
838
926
|
HDLRuby::High.top_user.send(name)
|
@@ -853,37 +941,121 @@ module HDLRuby::High::Std
|
|
853
941
|
# NOTE: for now, simply associate the channel to name.
|
854
942
|
chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc)
|
855
943
|
HDLRuby::High.space_reg(name) { chp }
|
944
|
+
# Save the port in the channe to avoid conflicting declaration.
|
945
|
+
@read_port = chp
|
946
|
+
@write_port = chp
|
856
947
|
return chp
|
857
948
|
end
|
858
949
|
|
950
|
+
# ## Declares the ports for accessing the channel as an inner component
|
951
|
+
# # and assigned them to +name+.
|
952
|
+
# def inner(name)
|
953
|
+
# # Ensure name is a symbol.
|
954
|
+
# name = name.to_sym
|
955
|
+
# # Access the ports
|
956
|
+
# loc_inputs = @accesser_inputs.merge(@reader_inputs).
|
957
|
+
# merge(@writer_inputs)
|
958
|
+
# loc_outputs = @accesser_outputs.merge(@reader_outputs).
|
959
|
+
# merge(@writer_outputs)
|
960
|
+
# loc_inouts = @accesser_inouts.merge(@reader_inouts).
|
961
|
+
# merge(@writer_inouts)
|
962
|
+
# locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
|
963
|
+
# # The generated port with corresponding channel port pairs.
|
964
|
+
# port_pairs = []
|
965
|
+
# # Add them to the current system.
|
966
|
+
# HDLRuby::High.cur_system.open do
|
967
|
+
# locs.each do |name,sig|
|
968
|
+
# port_pairs << [sig, sig.type.inner(name)]
|
969
|
+
# end
|
970
|
+
# end
|
971
|
+
# obj = self
|
972
|
+
# # Make the inner connection
|
973
|
+
# port_pairs.each do |sig, port|
|
974
|
+
# sig.parent.open do
|
975
|
+
# port.to_ref <= sig
|
976
|
+
# end
|
977
|
+
# end
|
978
|
+
|
979
|
+
# # Set ups the accesser's namespace
|
980
|
+
# loc_inputs.each do |name,sig|
|
981
|
+
# @accesser_namespace.add_method(sig.name) do
|
982
|
+
# HDLRuby::High.top_user.send(name)
|
983
|
+
# end
|
984
|
+
# end
|
985
|
+
# loc_outputs.each do |name,sig|
|
986
|
+
# @accesser_namespace.add_method(sig.name) do
|
987
|
+
# HDLRuby::High.top_user.send(name)
|
988
|
+
# end
|
989
|
+
# end
|
990
|
+
# loc_inouts.each do |name,sig|
|
991
|
+
# @accesser_namespace.add_method(sig.name) do
|
992
|
+
# HDLRuby::High.top_user.send(name)
|
993
|
+
# end
|
994
|
+
# end
|
995
|
+
|
996
|
+
# # Give access to the ports through name.
|
997
|
+
# # NOTE: for now, simply associate the channel to name.
|
998
|
+
# chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc)
|
999
|
+
# HDLRuby::High.space_reg(name) { chp }
|
1000
|
+
# return chp
|
1001
|
+
# end
|
1002
|
+
|
1003
|
+
|
859
1004
|
|
860
1005
|
## Performs a read on the channel using +args+ and +ruby_block+
|
861
1006
|
# as arguments.
|
1007
|
+
# NOTE:
|
1008
|
+
# * Will generate a port if not present.
|
1009
|
+
# * Will generate an error if a read is tempted while the read
|
1010
|
+
# port has been declared within another system.
|
862
1011
|
def read(*args,&ruby_block)
|
863
|
-
#
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
1012
|
+
# Is there a port to read?
|
1013
|
+
unless self.read_port then
|
1014
|
+
# No, generate a new one.
|
1015
|
+
# Is it possible to be inout?
|
1016
|
+
if self.inout? then
|
1017
|
+
# Yes, create an inout port.
|
1018
|
+
self.inout(HDLRuby.uniq_name)
|
1019
|
+
else
|
1020
|
+
# No, create an input port.
|
1021
|
+
self.input(HDLRuby.uniq_name)
|
1022
|
+
end
|
870
1023
|
end
|
871
|
-
|
1024
|
+
# Ensure the read port is within current system.
|
1025
|
+
unless self.read_port.scope.system != HDLRuby::High.cur_system then
|
1026
|
+
raise "Cannot read from a port external of current system for channel " + self.name
|
1027
|
+
end
|
1028
|
+
# Performs the read.
|
1029
|
+
self.read_port.read(*args,&ruby_block)
|
872
1030
|
end
|
873
1031
|
|
874
1032
|
## Performs a write on the channel using +args+ and +ruby_block+
|
875
1033
|
# as arguments.
|
1034
|
+
# NOTE:
|
1035
|
+
# * Will generate a port if not present.
|
1036
|
+
# * Will generate an error if a read is tempted while the read
|
1037
|
+
# port has been declared within another system.
|
876
1038
|
def write(*args,&ruby_block)
|
877
|
-
#
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
1039
|
+
# Is there a port to write?
|
1040
|
+
unless self.write_port then
|
1041
|
+
# No, generate a new one.
|
1042
|
+
# Is it possible to be inout?
|
1043
|
+
if self.inout? then
|
1044
|
+
# Yes, create an inout port.
|
1045
|
+
self.inout(HDLRuby.uniq_name)
|
1046
|
+
else
|
1047
|
+
# No, create an output port.
|
1048
|
+
self.output(HDLRuby.uniq_name)
|
1049
|
+
end
|
884
1050
|
end
|
885
|
-
|
1051
|
+
# Ensure the write port is within current system.
|
1052
|
+
unless self.write_port.scope.system != HDLRuby::High.cur_system then
|
1053
|
+
raise "Cannot write from a port external of current system for channel " + self.name
|
1054
|
+
end
|
1055
|
+
# Performs the write.
|
1056
|
+
self.write_port.write(*args,&ruby_block)
|
886
1057
|
end
|
1058
|
+
|
887
1059
|
|
888
1060
|
## Performs a reset on the channel using +args+ and +ruby_block+
|
889
1061
|
# as arguments.
|
@@ -902,10 +1074,12 @@ module HDLRuby::High::Std
|
|
902
1074
|
|
903
1075
|
|
904
1076
|
# Wrapper to make an object run like a channel port.
|
905
|
-
class ChannelPortObject
|
1077
|
+
class ChannelPortObject < ChannelPort
|
906
1078
|
# Create a new object wrapper for +obj+.
|
907
1079
|
def initialize(obj)
|
908
1080
|
@obj = obj
|
1081
|
+
|
1082
|
+
@scope = HDLRuby::High.cur_scope
|
909
1083
|
end
|
910
1084
|
|
911
1085
|
# Port read with arguments +args+ executing +ruby_block+ in
|
@@ -946,9 +1120,13 @@ module HDLRuby::High::Std
|
|
946
1120
|
|
947
1121
|
|
948
1122
|
# Wrap object +obj+ to act like a channel port.
|
949
|
-
def channel_port(obj)
|
1123
|
+
def self.channel_port(obj)
|
1124
|
+
return obj if obj.is_a?(ChannelPort) # No need to wrap.
|
950
1125
|
return ChannelPortObject.new(obj)
|
951
1126
|
end
|
1127
|
+
def channel_port(obj)
|
1128
|
+
return HDLRuby::High::Std.channel_port(obj)
|
1129
|
+
end
|
952
1130
|
end
|
953
1131
|
|
954
1132
|
|