HDLRuby 2.11.3 → 2.11.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -2
- data/ext/hruby_sim/hruby_rcsim_build.c +36 -11
- data/ext/hruby_sim/hruby_sim.h +13 -1
- data/ext/hruby_sim/hruby_sim_core.c +84 -50
- data/ext/hruby_sim/hruby_sim_tree_calc.c +14 -0
- data/ext/hruby_sim/hruby_sim_vcd.c +23 -9
- data/lib/HDLRuby/hdr_samples/repeat_bench.rb +48 -0
- data/lib/HDLRuby/hruby_high.rb +11 -6
- data/lib/HDLRuby/hruby_low.rb +27 -17
- data/lib/HDLRuby/hruby_low2c.rb +31 -7
- data/lib/HDLRuby/hruby_rcsim.rb +16 -2
- data/lib/HDLRuby/hruby_rsim.rb +154 -79
- data/lib/HDLRuby/hruby_rsim_vcd.rb +181 -10
- data/lib/HDLRuby/hruby_verilog.rb +71 -58
- data/lib/HDLRuby/version.rb +1 -1
- metadata +3 -2
data/lib/HDLRuby/hruby_low2c.rb
CHANGED
@@ -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
|
-
|
1814
|
-
|
1815
|
-
|
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
|
data/lib/HDLRuby/hruby_rcsim.rb
CHANGED
@@ -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
|
-
|
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.
|
687
|
+
RCSim.rcsim_set_owner(@rcstatement,owner)
|
674
688
|
end
|
675
689
|
|
676
690
|
# Add the inner signals.
|
data/lib/HDLRuby/hruby_rsim.rb
CHANGED
@@ -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
|
-
|
72
|
-
#
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
#
|
110
|
-
|
111
|
-
#
|
112
|
-
@sig_active.
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
-
#
|
119
|
-
@
|
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
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
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
|
-
##
|
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} #{
|
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"
|
50
|
-
@vcdout << "
|
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 <<
|
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
|