HDLRuby 2.11.3 → 2.11.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -843,6 +843,9 @@ module HDLRuby::Low
843
843
  ## Extends the SignalI class with generation of C text.
844
844
  class SignalI
845
845
 
846
+ # The id of a signal in the simulator.
847
+ @@signal_id = 0
848
+
846
849
  ## Generates the C text for an access to the signal.
847
850
  # +level+ is the hierachical level of the object.
848
851
  # def to_c_signal(level = 0)
@@ -881,6 +884,8 @@ module HDLRuby::Low
881
884
  res << "SignalI signalI = malloc(sizeof(SignalIS));\n"
882
885
  res << " " * (level+1)*3
883
886
  res << "signalI->kind = SIGNALI;\n";
887
+ res << "signalI->id = #{@@signal_id};\n"
888
+ @@signal_id = @@signal_id+1;
884
889
 
885
890
  # Sets the global variable of the signal.
886
891
  res << "\n"
@@ -1803,20 +1808,39 @@ module HDLRuby::Low
1803
1808
  ## Extends the TimeRepeat class with generation of C text.
1804
1809
  class TimeRepeat
1805
1810
 
1811
+ # # Generates the C text of the equivalent HDLRuby code.
1812
+ # # +level+ is the hierachical level of the object.
1813
+ # # def to_c(level = 0)
1814
+ # def to_c(res,level = 0)
1815
+ # # The resulting string.
1816
+ # # res = " " * level*3
1817
+ # res << " " * level*3
1818
+ # # Generate an infinite loop executing the block and waiting.
1819
+ # res << "for(;;) {\n"
1820
+ # # res << "#{self.statement.to_c(level+1)}\n"
1821
+ # self.statement.to_c(res,level+1)
1822
+ # res << "\n"
1823
+ # res << " " * (level+1)*3
1824
+ # res << Low2C.wait_code(self,level)
1825
+ # # Return the resulting string.
1826
+ # return res
1827
+ # end
1828
+
1806
1829
  # Generates the C text of the equivalent HDLRuby code.
1807
1830
  # +level+ is the hierachical level of the object.
1808
1831
  # def to_c(level = 0)
1809
1832
  def to_c(res,level = 0)
1810
1833
  # The resulting string.
1811
- # res = " " * level*3
1812
1834
  res << " " * level*3
1813
- # Generate an infinite loop executing the block and waiting.
1814
- res << "for(;;) {\n"
1815
- # res << "#{self.statement.to_c(level+1)}\n"
1835
+ if (number < 0) then
1836
+ # Generate an infinite loop executing the block and waiting.
1837
+ res << "for(;;) {\n"
1838
+ else
1839
+ # Generate a finite loop.
1840
+ res << "for(long long i = 0; i<#{self.number}; ++i) {\n"
1841
+ end
1816
1842
  self.statement.to_c(res,level+1)
1817
- res << "\n"
1818
- res << " " * (level+1)*3
1819
- res << Low2C.wait_code(self,level)
1843
+ res << " " * level*3 << "}\n"
1820
1844
  # Return the resulting string.
1821
1845
  return res
1822
1846
  end
@@ -654,7 +654,21 @@ module HDLRuby::High
654
654
  ## Extends the TimeRepeat class for hybrid Ruby-C simulation.
655
655
  class TimeRepeat
656
656
  attr_reader :rcstatement
657
- # TODO!!!
657
+
658
+ # Generate the C description of the hardware case.
659
+ # +owner+ is a link to the C description of the owner behavior if any.
660
+ def to_rcsim(owner = nil)
661
+ # Create the timeRepeat C object.
662
+ @rcstatement = RCSim.rcsim_make_timeRepeat(self.number,
663
+ self.statement.to_rcsim)
664
+
665
+ # Sets the owner if any.
666
+ if owner then
667
+ RCSim.rcsim_set_owner(@rcstatement,owner)
668
+ end
669
+
670
+ return @rcstatement
671
+ end
658
672
  end
659
673
 
660
674
 
@@ -670,7 +684,7 @@ module HDLRuby::High
670
684
 
671
685
  # Sets the owner if any.
672
686
  if owner then
673
- RCSim.rcsim_set_block_owner(@rcstatement,owner)
687
+ RCSim.rcsim_set_owner(@rcstatement,owner)
674
688
  end
675
689
 
676
690
  # Add the inner signals.
@@ -16,6 +16,9 @@ module HDLRuby::High
16
16
  # Enhance a system type with Ruby simulation.
17
17
  class SystemT
18
18
 
19
+ # Tell if the simulation is in multithread mode or not.
20
+ attr_reader :multithread
21
+
19
22
  ## Add timed behavior +beh+.
20
23
  # Returns the id of the timed behavior.
21
24
  def add_timed_behavior(beh)
@@ -36,6 +39,50 @@ module HDLRuby::High
36
39
  @sig_active << sig
37
40
  end
38
41
 
42
+ ## Advance the global simulator.
43
+ def advance
44
+ # Display the time
45
+ self.show_time
46
+ shown_values = {}
47
+ # Get the behaviors waiting on activated signals.
48
+ until @sig_active.empty? do
49
+ # # Update the signals.
50
+ # @sig_active.each { |sig| sig.c_value = sig.f_value }
51
+ # puts "sig_active.size=#{@sig_active.size}"
52
+ # Look for the behavior sensitive to the signals.
53
+ @sig_active.each do |sig|
54
+ sig.each_anyedge { |beh| @sig_exec << beh }
55
+ if (sig.c_value.zero? && !sig.f_value.zero?) then
56
+ # puts "sig.c_value=#{sig.c_value.content}"
57
+ sig.each_posedge { |beh| @sig_exec << beh }
58
+ elsif (!sig.c_value.zero? && sig.f_value.zero?) then
59
+ sig.each_negedge { |beh| @sig_exec << beh }
60
+ end
61
+ end
62
+ # Update the signals.
63
+ @sig_active.each { |sig| sig.c_value = sig.f_value }
64
+ # puts "first @sig_exec.size=#{@sig_exec.size}"
65
+ @sig_exec.uniq! {|beh| beh.object_id }
66
+ # Display the activated signals.
67
+ @sig_active.each do |sig|
68
+ if !shown_values[sig].eql?(sig.f_value) then
69
+ self.show_signal(sig)
70
+ shown_values[sig] = sig.f_value
71
+ end
72
+ end
73
+ # Clear the list of active signals.
74
+ @sig_active.clear
75
+ # puts "sig_exec.size=#{@sig_exec.size}"
76
+ # Execute the relevant behaviors and connections.
77
+ @sig_exec.each { |obj| obj.execute(:par) }
78
+ @sig_exec.clear
79
+ @sig_active.uniq! {|sig| sig.object_id }
80
+ # puts "@sig_active.size=#{@sig_active.size}"
81
+ # Advance time.
82
+ @time = (@timed_behaviors.min {|b0,b1| b0.time <=> b1.time }).time
83
+ end
84
+ end
85
+
39
86
  ## Run the simulation from the current systemT and outputs the resuts
40
87
  # on simout.
41
88
  def sim(simout)
@@ -43,15 +90,6 @@ module HDLRuby::High
43
90
  HDLRuby.show "#{Time.now}#{show_mem}"
44
91
  # Merge the included.
45
92
  self.merge_included!
46
- # Initializes the run mutex and the conditions.
47
- @mutex = Mutex.new
48
- @master = ConditionVariable.new
49
- @master_flag = 0
50
- @slave = ConditionVariable.new
51
- @slave_flags_not = 0
52
- @num_done = 0
53
- # @lock = 0
54
- # @runs = 0
55
93
  # Initializes the time.
56
94
  @time = 0
57
95
  # Initializes the time and signals execution buffers.
@@ -68,72 +106,93 @@ module HDLRuby::High
68
106
  self.init_sim(self)
69
107
  # Initialize the displayer.
70
108
  self.show_init(simout)
71
- # exit
72
- # First all the timed behaviors are to be executed.
73
- @timed_behaviors.each {|beh| @tim_exec << beh }
74
- # But starts locked.
75
- @slave_flags_not = 2**@timed_behaviors.size - 1
76
- # Starts the threads.
77
- @timed_behaviors.each {|beh| beh.make_thread }
78
-
79
- HDLRuby.show "Starting Ruby-level simulator..."
80
- HDLRuby.show "#{Time.now}#{show_mem}"
81
- # Run the simulation.
82
- self.run_init do
83
- # # Wake the behaviors.
84
- # @timed_behaviors.each {|beh| beh.run }
85
- until @tim_exec.empty? do
86
- # Display the time
87
- self.show_time
88
- # Execute the time behaviors that are ready.
89
- self.run_ack
90
- self.run_wait
91
- shown_values = {}
92
- # Get the behaviors waiting on activated signals.
93
- until @sig_active.empty? do
94
- # # Update the signals.
95
- # @sig_active.each { |sig| sig.c_value = sig.f_value }
96
- # puts "sig_active.size=#{@sig_active.size}"
97
- # Look for the behavior sensitive to the signals.
98
- @sig_active.each do |sig|
99
- sig.each_anyedge { |beh| @sig_exec << beh }
100
- if (sig.c_value.zero? && !sig.f_value.zero?) then
101
- # puts "sig.c_value=#{sig.c_value.content}"
102
- sig.each_posedge { |beh| @sig_exec << beh }
103
- elsif (!sig.c_value.zero? && sig.f_value.zero?) then
104
- sig.each_negedge { |beh| @sig_exec << beh }
105
- end
106
- end
107
- # Update the signals.
108
- @sig_active.each { |sig| sig.c_value = sig.f_value }
109
- # puts "first @sig_exec.size=#{@sig_exec.size}"
110
- @sig_exec.uniq! {|beh| beh.object_id }
111
- # Display the activated signals.
112
- @sig_active.each do |sig|
113
- if !shown_values[sig].eql?(sig.f_value) then
114
- self.show_signal(sig)
115
- shown_values[sig] = sig.f_value
116
- end
109
+
110
+ # Is there more than one timed behavior.
111
+ if @total_timed_behaviors <= 1 then
112
+ # No, no need of multithreading.
113
+ @multithread = false
114
+ # Simple execute the block of the behavior.
115
+ @timed_behaviors[0].block.execute(:seq)
116
+ else
117
+ # Yes, need of multithreading.
118
+ @multithread = true
119
+ # Initializes the run mutex and the conditions.
120
+ @mutex = Mutex.new
121
+ @master = ConditionVariable.new
122
+ @master_flag = 0
123
+ @slave = ConditionVariable.new
124
+ @slave_flags_not = 0
125
+ @num_done = 0
126
+
127
+ # First all the timed behaviors are to be executed.
128
+ @timed_behaviors.each {|beh| @tim_exec << beh }
129
+ # But starts locked.
130
+ @slave_flags_not = 2**@timed_behaviors.size - 1
131
+ # Starts the threads.
132
+ @timed_behaviors.each {|beh| beh.make_thread }
133
+
134
+ HDLRuby.show "Starting Ruby-level simulator..."
135
+ HDLRuby.show "#{Time.now}#{show_mem}"
136
+ # Run the simulation.
137
+ self.run_init do
138
+ # # Wake the behaviors.
139
+ # @timed_behaviors.each {|beh| beh.run }
140
+ until @tim_exec.empty? do
141
+ # Execute the time behaviors that are ready.
142
+ self.run_ack
143
+ self.run_wait
144
+ # Advance the global simulator.
145
+ self.advance
146
+ # # Display the time
147
+ # self.show_time
148
+ # shown_values = {}
149
+ # # Get the behaviors waiting on activated signals.
150
+ # until @sig_active.empty? do
151
+ # # # Update the signals.
152
+ # # @sig_active.each { |sig| sig.c_value = sig.f_value }
153
+ # # puts "sig_active.size=#{@sig_active.size}"
154
+ # # Look for the behavior sensitive to the signals.
155
+ # @sig_active.each do |sig|
156
+ # sig.each_anyedge { |beh| @sig_exec << beh }
157
+ # if (sig.c_value.zero? && !sig.f_value.zero?) then
158
+ # # puts "sig.c_value=#{sig.c_value.content}"
159
+ # sig.each_posedge { |beh| @sig_exec << beh }
160
+ # elsif (!sig.c_value.zero? && sig.f_value.zero?) then
161
+ # sig.each_negedge { |beh| @sig_exec << beh }
162
+ # end
163
+ # end
164
+ # # Update the signals.
165
+ # @sig_active.each { |sig| sig.c_value = sig.f_value }
166
+ # # puts "first @sig_exec.size=#{@sig_exec.size}"
167
+ # @sig_exec.uniq! {|beh| beh.object_id }
168
+ # # Display the activated signals.
169
+ # @sig_active.each do |sig|
170
+ # if !shown_values[sig].eql?(sig.f_value) then
171
+ # self.show_signal(sig)
172
+ # shown_values[sig] = sig.f_value
173
+ # end
174
+ # end
175
+ # # Clear the list of active signals.
176
+ # @sig_active.clear
177
+ # # puts "sig_exec.size=#{@sig_exec.size}"
178
+ # # Execute the relevant behaviors and connections.
179
+ # @sig_exec.each { |obj| obj.execute(:par) }
180
+ # @sig_exec.clear
181
+ # @sig_active.uniq! {|sig| sig.object_id }
182
+ # # puts "@sig_active.size=#{@sig_active.size}"
183
+ # end
184
+
185
+ # # Advance time.
186
+ # @time = (@timed_behaviors.min {|b0,b1| b0.time <=> b1.time }).time
187
+ break if @timed_behaviors.empty?
188
+ # Schedule the next timed behavior to execute.
189
+ @tim_exec = []
190
+ @timed_behaviors.each do |beh|
191
+ @tim_exec << beh if beh.time == @time
117
192
  end
118
- # Clear the list of active signals.
119
- @sig_active.clear
120
- # puts "sig_exec.size=#{@sig_exec.size}"
121
- # Execute the relevant behaviors and connections.
122
- @sig_exec.each { |obj| obj.execute(:par) }
123
- @sig_exec.clear
124
- @sig_active.uniq! {|sig| sig.object_id }
125
- # puts "@sig_active.size=#{@sig_active.size}"
126
- end
127
- break if @timed_behaviors.empty?
128
- # Advance time.
129
- @time = (@timed_behaviors.min {|b0,b1| b0.time <=> b1.time }).time
130
- # Schedule the next timed behavior to execute.
131
- @tim_exec = []
132
- @timed_behaviors.each do |beh|
133
- @tim_exec << beh if beh.time == @time
193
+ # puts "@tim_exec.size=#{@tim_exec.size}"
194
+ # puts "@timed_bevaviors.size=#{@timed_behaviors.size}"
134
195
  end
135
- # puts "@tim_exec.size=#{@tim_exec.size}"
136
- # puts "@timed_bevaviors.size=#{@timed_behaviors.size}"
137
196
  end
138
197
  end
139
198
  end
@@ -358,7 +417,8 @@ module HDLRuby::High
358
417
  begin
359
418
  # puts "Starting thread"
360
419
  systemT.run_req(@id)
361
- self.block.execute(:par)
420
+ # self.block.execute(:par)
421
+ self.block.execute(:seq)
362
422
  # puts "Ending thread"
363
423
  rescue => e
364
424
  puts "Got exception: #{e.full_message}"
@@ -690,10 +750,16 @@ module HDLRuby::High
690
750
  def execute(mode)
691
751
  @behavior ||= self.behavior
692
752
  @behavior.time += self.delay.time_ps
693
- # puts "Stopping #{@behavior.object_id} (@behavior.time=#{@behavior.time})..."
694
- @sim.run_done(@behavior.id)
695
- # puts "Rerunning #{@behavior.object_id} (@behavior.time=#{@behavior.time})..."
696
- @sim.run_req(@behavior.id)
753
+ if @sim.multithread then
754
+ # Multi thread mode: synchronize.
755
+ # puts "Stopping #{@behavior.object_id} (@behavior.time=#{@behavior.time})..."
756
+ @sim.run_done(@behavior.id)
757
+ # puts "Rerunning #{@behavior.object_id} (@behavior.time=#{@behavior.time})..."
758
+ @sim.run_req(@behavior.id)
759
+ else
760
+ # No thread mode, need to advance the global simulator.
761
+ @sim.advance
762
+ end
697
763
  end
698
764
  end
699
765
 
@@ -701,7 +767,16 @@ module HDLRuby::High
701
767
  ##
702
768
  # Describes a timed loop statement: not synthesizable!
703
769
  class TimeRepeat
704
- ## Deprecated
770
+ ## Initialize the simulation for system +systemT+.
771
+ def init_sim(systemT)
772
+ # Recurde on the statement.
773
+ self.statement.init_sim(systemT)
774
+ end
775
+
776
+ ## Executes the statement.
777
+ def execute(mode)
778
+ self.number.times { self.statement.execute(mode) }
779
+ end
705
780
  end
706
781
 
707
782
 
@@ -11,6 +11,35 @@ module HDLRuby::High
11
11
  return name.to_s.gsub(/[^a-zA-Z0-9_$]/,"$")
12
12
  end
13
13
 
14
+ ## Converts a bit string to a vcd format.
15
+ def self.vcd_bitstr(str)
16
+ if str.length > 1 then
17
+ return "b" + str + " "
18
+ else
19
+ return str
20
+ end
21
+ end
22
+
23
+ ## Converts a HDLRuby object to a VCD id string.
24
+ @@rsim_object_idstr = { }
25
+ @@rsim_object_idstr_count = 0
26
+ def self.vcd_idstr(obj)
27
+ idstr = @@rsim_object_idstr[obj]
28
+ unless idstr then
29
+ # Must generate a new id string.
30
+ chars = []
31
+ id = @@rsim_object_idstr_count
32
+ @@rsim_object_idstr_count += 1
33
+ loop do
34
+ chars << ((id % (127-33)) + 33).chr
35
+ break if ((id=id/(127-33)) == 0)
36
+ end
37
+ idstr = chars.join
38
+ @@rsim_object_idstr[obj] = idstr
39
+ end
40
+ return idstr
41
+ end
42
+
14
43
  ##
15
44
  # Enhance the system type class with VCD support.
16
45
  class SystemT
@@ -40,14 +69,24 @@ module HDLRuby::High
40
69
  # Closes the header.
41
70
  @vcdout << "$enddefinitions $end\n"
42
71
  # Initializes the variables with their name.
43
- @vars_with_fullname = self.get_vars_with_fullname
72
+ # @vars_with_fullname = self.get_vars_with_fullname
73
+ @vars_with_idstr = self.get_vars_with_idstr
44
74
  @vcdout << "$dumpvars\n"
45
- @vars_with_fullname.each_pair do |sig,fullname|
75
+ # @vars_with_fullname.each_pair do |sig,fullname|
76
+ # if sig.f_value then
77
+ # @vcdout << " b#{sig.f_value.to_vstr} #{fullname}\n"
78
+ # else
79
+ # @vcdout << " b#{"x"} #{fullname}\n"
80
+ # end
81
+ # end
82
+ @vars_with_idstr.each_pair do |sig,idstr|
46
83
  if sig.f_value then
47
- @vcdout << " b#{sig.f_value.to_vstr} #{fullname}\n"
84
+ # @vcdout << " b#{sig.f_value.to_vstr} #{idstr}\n"
85
+ @vcdout << HDLRuby::High.vcd_bitstr(sig.f_value.to_vstr) <<
86
+ idstr << "\n"
48
87
  else
49
- # @vcdout << " b#{"x"*sig.type.width} #{fullname}\n"
50
- @vcdout << " b#{"x"} #{fullname}\n"
88
+ # @vcdout << " b#{"x"} #{idstr}\n"
89
+ @vcdout << HDLRuby::High.vcd_bitstr("x") << idstr << "\n"
51
90
  end
52
91
  end
53
92
  @vcdout << "$end\n"
@@ -63,6 +102,16 @@ module HDLRuby::High
63
102
  return self.scope.get_vars_with_fullname(vars_with_fullname)
64
103
  end
65
104
 
105
+ ## Gets the VCD variables with their id string.
106
+ def get_vars_with_idstr(vars_with_idstr = {})
107
+ # Adds the signals of the interface of the system.
108
+ self.each_signal do |sig|
109
+ vars_with_idstr[sig] = HDLRuby::High.vcd_idstr(sig)
110
+ end
111
+ # Recurse on the scope.
112
+ return self.scope.get_vars_with_idstr(vars_with_idstr)
113
+ end
114
+
66
115
  ## Shows the hierarchy of the variables.
67
116
  def show_hierarchy(vcdout)
68
117
  # puts "show_hierarchy for module #{self} (#{self.name})"
@@ -72,7 +121,8 @@ module HDLRuby::High
72
121
  self.each_signal do |sig|
73
122
  # puts "showing signal #{HDLRuby::High.vcd_name(sig.fullname)}"
74
123
  vcdout << "$var wire #{sig.type.width} "
75
- vcdout << "#{HDLRuby::High.vcd_name(sig.fullname)} "
124
+ # vcdout << "#{HDLRuby::High.vcd_name(sig.fullname)} "
125
+ vcdout << "#{HDLRuby::High.vcd_idstr(sig)} "
76
126
  vcdout << "#{HDLRuby::High.vcd_name(sig.name)} $end\n"
77
127
  end
78
128
  # Recurse on the scope.
@@ -88,8 +138,9 @@ module HDLRuby::High
88
138
 
89
139
  ## Displays the value of signal +sig+.
90
140
  def show_signal(sig)
91
- @vcdout << "b#{sig.f_value.to_vstr} "
92
- @vcdout << "#{@vars_with_fullname[sig]}\n"
141
+ # @vcdout << "b#{sig.f_value.to_vstr} "
142
+ @vcdout << HDLRuby::High.vcd_bitstr(sig.f_value.to_vstr)
143
+ @vcdout << "#{@vars_with_idstr[sig]}\n"
93
144
  end
94
145
 
95
146
  ## Displays value +val+.
@@ -121,7 +172,8 @@ module HDLRuby::High
121
172
  self.each_inner do |sig|
122
173
  # puts "showing inner signal #{HDLRuby::High.vcd_name(sig.fullname)}"
123
174
  vcdout << "$var wire #{sig.type.width} "
124
- vcdout << "#{HDLRuby::High.vcd_name(sig.fullname)} "
175
+ # vcdout << "#{HDLRuby::High.vcd_name(sig.fullname)} "
176
+ vcdout << "#{HDLRuby::High.vcd_idstr(sig)} "
125
177
  vcdout << "#{HDLRuby::High.vcd_name(sig.name)} $end\n"
126
178
  end
127
179
  # Recurse on the behaviors' blocks
@@ -162,6 +214,27 @@ module HDLRuby::High
162
214
  end
163
215
  return vars_with_fullname
164
216
  end
217
+
218
+ ## Gets the VCD variables with their id string.
219
+ def get_vars_with_idstr(vars_with_idstr = {})
220
+ # Adds the inner signals.
221
+ self.each_inner do |sig|
222
+ vars_with_idstr[sig] = HDLRuby::High.vcd_idstr(sig)
223
+ end
224
+ # Recurse on the behaviors' blocks
225
+ self.each_behavior do |beh|
226
+ beh.block.get_vars_with_idstr(vars_with_idstr)
227
+ end
228
+ # Recurse on the systemI's Eigen system.
229
+ self.each_systemI do |sys|
230
+ sys.systemT.get_vars_with_idstr(vars_with_idstr)
231
+ end
232
+ # Recurse on the subscopes.
233
+ self.each_scope do |scope|
234
+ scope.get_vars_with_idstr(vars_with_idstr)
235
+ end
236
+ return vars_with_idstr
237
+ end
165
238
  end
166
239
 
167
240
 
@@ -177,6 +250,31 @@ module HDLRuby::High
177
250
  def get_vars_with_fullname(vars_with_fullname = {})
178
251
  # By default: nothing to do
179
252
  end
253
+
254
+ ## Gets the VCD variables with their id string.
255
+ def get_vars_with_idstr(vars_with_idstr = {})
256
+ # By default: nothing to do
257
+ end
258
+ end
259
+
260
+ ##
261
+ # Enhance the TimeRepeat class with VCD support.
262
+ class TimeRepeat
263
+ ## Shows the hierarchy of the variables.
264
+ def show_hierarchy(vcdout)
265
+ # Recurse on the statement.
266
+ self.statement.show_hierarchy(vcdout)
267
+ end
268
+
269
+ ## Gets the VCD variables with their long name.
270
+ def get_vars_with_fullname(vars_with_fullname = {})
271
+ # By default: nothing to do
272
+ end
273
+
274
+ ## Gets the VCD variables with their idstr.
275
+ def get_vars_with_idstr(vars_with_idstr = {})
276
+ # By default: nothing to do
277
+ end
180
278
  end
181
279
 
182
280
  ##
@@ -191,6 +289,11 @@ module HDLRuby::High
191
289
  def get_vars_with_fullname(vars_with_fullname = {})
192
290
  # By default: nothing to do
193
291
  end
292
+
293
+ ## Gets the VCD variables with their id string.
294
+ def get_vars_with_idstr(vars_with_idstr = {})
295
+ # By default: nothing to do
296
+ end
194
297
  end
195
298
 
196
299
  ##
@@ -205,6 +308,11 @@ module HDLRuby::High
205
308
  def get_vars_with_fullname(vars_with_fullname = {})
206
309
  # By default: nothing to do
207
310
  end
311
+
312
+ ## Gets the VCD variables with their id string.
313
+ def get_vars_with_idstr(vars_with_idstr = {})
314
+ # By default: nothing to do
315
+ end
208
316
  end
209
317
 
210
318
 
@@ -223,7 +331,8 @@ module HDLRuby::High
223
331
  self.each_inner do |sig|
224
332
  # puts "showing inner signal #{HDLRuby::High.vcd_name(sig.fullname)}"
225
333
  vcdout << "$var wire #{sig.type.width} "
226
- vcdout << "#{HDLRuby::High.vcd_name(sig.fullname)} "
334
+ # vcdout << "#{HDLRuby::High.vcd_name(sig.fullname)} "
335
+ vcdout << "#{HDLRuby::High.vcd_idstr(sig)} "
227
336
  vcdout << "#{HDLRuby::High.vcd_name(sig.name)} $end\n"
228
337
  end
229
338
  # Recurse on the statements
@@ -248,6 +357,19 @@ module HDLRuby::High
248
357
  end
249
358
  return vars_with_fullname
250
359
  end
360
+
361
+ ## Gets the VCD variables with their id string.
362
+ def get_vars_with_idstr(vars_with_idstr = {})
363
+ # Adds the inner signals.
364
+ self.each_inner do |sig|
365
+ vars_with_idstr[sig] = HDLRuby::High.vcd_idstr(sig)
366
+ end
367
+ # Recurse on the statements.
368
+ self.each_statement do |stmnt|
369
+ stmnt.get_vars_with_idstr(vars_with_idstr)
370
+ end
371
+ return vars_with_idstr
372
+ end
251
373
  end
252
374
 
253
375
 
@@ -292,6 +414,19 @@ module HDLRuby::High
292
414
  self.no.get_vars_with_fullname(vars_with_fullname) if self.no
293
415
  return vars_with_fullname
294
416
  end
417
+
418
+ ## Gets the VCD variables with their id string.
419
+ def get_vars_with_idstr(vars_with_idstr = {})
420
+ # Recurse on the yes.
421
+ self.yes.get_vars_with_idstr(vars_with_idstr)
422
+ # Recurse on the noifs.
423
+ self.each_noif do |cond,stmnt|
424
+ stmnt.get_vars_with_idstr(vars_with_idstr)
425
+ end
426
+ # Recure on the no if any.
427
+ self.no.get_vars_with_idstr(vars_with_idstr) if self.no
428
+ return vars_with_idstr
429
+ end
295
430
  end
296
431
 
297
432
 
@@ -318,5 +453,41 @@ module HDLRuby::High
318
453
  self.default.get_vars_with_fullname(vars_with_fullname)
319
454
  return vars_with_fullname
320
455
  end
456
+
457
+ ## Gets the VCD variables with their id string.
458
+ def get_vars_with_idstr(vars_with_idstr = {})
459
+ # Recurse on each when.
460
+ self.each_when do |w|
461
+ w.statement.get_vars_with_idstr(vars_with_idstr)
462
+ end
463
+ # Recurse on the default if any.
464
+ self.default.get_vars_with_idstr(vars_with_idstr)
465
+ return vars_with_idstr
466
+ end
321
467
  end
468
+
469
+ ##
470
+ # Enhance the TimeRepeat class with VCD support.
471
+ class TimeRepeat
472
+ ## Shows the hierarchy of the variables.
473
+ def show_hierarchy(vcdout)
474
+ # Recurse on the statement.
475
+ self.statement.show_hierarchy(vcdout)
476
+ end
477
+
478
+ ## Gets the VCD variables with their long name.
479
+ def get_vars_with_fullname(vars_with_fullname = {})
480
+ # Recurse on the statement.
481
+ self.statement.get_vars_with_fullname(vars_with_fullname)
482
+ return vars_with_fullname
483
+ end
484
+
485
+ ## Gets the VCD variables with their id string.
486
+ def get_vars_with_idstr(vars_with_idstr = {})
487
+ # Recurse on the statement.
488
+ self.statement.get_vars_with_idstr(vars_with_idstr)
489
+ return vars_with_idstr
490
+ end
491
+ end
492
+
322
493
  end