HDLRuby 2.2.16 → 2.3.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|