HDLRuby 2.11.3 → 2.11.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.
@@ -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