HDLRuby 2.11.4 → 2.11.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -29,7 +29,9 @@ module HDLRuby::Low
29
29
  if scope.each_connection.to_a.any? then
30
30
  inputs_blk = Block.new(:par)
31
31
  outputs_blk = Block.new(:par)
32
- timed_blk = TimeBlock.new(:seq)
32
+ # Timed block is not necessary anymore for initialization.
33
+ # timed_blk = TimeBlock.new(:seq)
34
+ timed_blk = Block.new(:seq)
33
35
  scope.each_connection do |connection|
34
36
  # puts "For connection: #{connection}"
35
37
  # Check the left and right of the connection
@@ -134,7 +136,9 @@ module HDLRuby::Low
134
136
  scope.add_behavior(Behavior.new(outputs_blk))
135
137
  end
136
138
  if timed_blk.each_statement.any? then
137
- scope.add_behavior(TimeBehavior.new(timed_blk))
139
+ # No more required to be timed.
140
+ # scope.add_behavior(TimeBehavior.new(timed_blk))
141
+ scope.add_behavior(Behavior.new(timed_blk))
138
142
  end
139
143
  end
140
144
  end
@@ -78,11 +78,13 @@ module HDLRuby::High
78
78
 
79
79
 
80
80
  ## Starts the simulation for top system +top+.
81
- # NOTE: +name+ is the name of the simulation and +vcd+ tells if
82
- # the vcd generation is used and +outpath+ is the path where
83
- # the faile is to save.
84
- def self.rcsim(top,name,outpath,vcd)
85
- RCSim.rcsim_main(top.rcsystemT,outpath +"/" + name,vcd)
81
+ # NOTE: +name+ is the name of the simulation, +outpath+ is the path where
82
+ # the output is to save, and +outmode+ is the output mode as follows:
83
+ # 0: standard
84
+ # 1: mute
85
+ # 2: vcd
86
+ def self.rcsim(top,name,outpath,outmode)
87
+ RCSim.rcsim_main(top.rcsystemT,outpath +"/" + name,outmode)
86
88
  end
87
89
 
88
90
 
@@ -741,7 +743,7 @@ module HDLRuby::High
741
743
  # Create and add the events.
742
744
  rcevs = []
743
745
  self.right.each_node_deep do |node|
744
- if node.is_a?(RefObject) then
746
+ if node.is_a?(RefObject) && !node.parent.is_a?(RefObject) then
745
747
  ev = RCSim.rcsim_make_event(:anyedge,node.to_rcsim)
746
748
  RCSim.rcsim_set_owner(ev,@rcbehavior)
747
749
  rcevs << ev
@@ -786,16 +788,24 @@ module HDLRuby::High
786
788
  def to_rcsim
787
789
  # Create the value C object.
788
790
  if self.content.is_a?(::Integer) then
789
- if self.content.bit_length <= 63 then
790
- return RCSim.rcsim_make_value_numeric(self.type.to_rcsim,
791
- self.content)
791
+ # puts "self.type.width=#{self.type.width} and content=#{self.content}" ; $stdout.flush
792
+ if self.type.width <= 64 then
793
+ if self.content.bit_length <= 63 then
794
+ return RCSim.rcsim_make_value_numeric(self.type.to_rcsim,
795
+ self.content)
796
+ else
797
+ return RCSim.rcsim_make_value_numeric(self.type.to_rcsim,
798
+ self.content & 0xFFFFFFFFFFFF)
799
+ end
792
800
  else
793
- str = self.content.to_s(2)
794
- if str[-1] == "-" then
795
- str[-1] = "1"
796
- elsif str[-1] == "1" then
797
- str = "0" + str
801
+ if self.content < 0 then
802
+ str = (2**self.type.width + self.content).to_s(2)
803
+ str = "1" * (self.type.width-str.length) + str
804
+ else
805
+ str = self.content.to_s(2)
806
+ str = "0" * (self.type.width-str.length) + str
798
807
  end
808
+ # puts "now str=#{str} (#{str.length})" ; $stdout.flush
799
809
  return RCSim.rcsim_make_value_bitstring(self.type.to_rcsim,
800
810
  str.reverse)
801
811
  end
@@ -945,7 +955,7 @@ module HDLRuby::High
945
955
  # RCSim.rcsim_add_refConcat_ref(rcref,ref.to_rcsim)
946
956
  # end
947
957
  if self.each_ref.any? then
948
- RCSim.rcsim_add_refConcat_refs(rcref,self.each_ref(&:to_rcsim))
958
+ RCSim.rcsim_add_refConcat_refs(rcref,self.each_ref.map(&:to_rcsim))
949
959
  end
950
960
 
951
961
  return rcref
@@ -16,6 +16,14 @@ 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
+
22
+ ## Add untimed objet +obj+
23
+ def add_untimed(obj)
24
+ @untimeds << obj
25
+ end
26
+
19
27
  ## Add timed behavior +beh+.
20
28
  # Returns the id of the timed behavior.
21
29
  def add_timed_behavior(beh)
@@ -36,6 +44,63 @@ module HDLRuby::High
36
44
  @sig_active << sig
37
45
  end
38
46
 
47
+ ## Advance the global simulator.
48
+ def advance
49
+ # # Display the time
50
+ # self.show_time
51
+ shown_values = {}
52
+ # Get the behaviors waiting on activated signals.
53
+ until @sig_active.empty? do
54
+ # puts "sig_active.size=#{@sig_active.size}"
55
+ # puts "sig_active=#{@sig_active.map {|sig| sig.fullname}}"
56
+ # Look for the behavior sensitive to the signals.
57
+ # @sig_active.each do |sig|
58
+ # sig.each_anyedge { |beh| @sig_exec << beh }
59
+ # if (sig.c_value.zero? && !sig.f_value.zero?) then
60
+ # # puts "sig.c_value=#{sig.c_value.content}"
61
+ # sig.each_posedge { |beh| @sig_exec << beh }
62
+ # elsif (!sig.c_value.zero? && sig.f_value.zero?) then
63
+ # sig.each_negedge { |beh| @sig_exec << beh }
64
+ # end
65
+ # end
66
+ @sig_active.each do |sig|
67
+ next if (sig.c_value.eql?(sig.f_value))
68
+ # next if (sig.c_value.to_vstr == sig.f_value.to_vstr)
69
+ # puts "sig.c_value: #{sig.c_value.to_vstr}, sig.f_value=#{sig.f_value.to_vstr}"
70
+ sig.each_anyedge { |beh| @sig_exec << beh }
71
+ if (sig.c_value.zero?) then
72
+ # puts "sig.c_value=#{sig.c_value.content}"
73
+ sig.each_posedge { |beh| @sig_exec << beh }
74
+ elsif (!sig.c_value.zero?) then
75
+ sig.each_negedge { |beh| @sig_exec << beh }
76
+ end
77
+ end
78
+ # Update the signals.
79
+ @sig_active.each { |sig| sig.c_value = sig.f_value }
80
+ # puts "first @sig_exec.size=#{@sig_exec.size}"
81
+ @sig_exec.uniq! {|beh| beh.object_id }
82
+ # Display the activated signals.
83
+ @sig_active.each do |sig|
84
+ if !shown_values[sig].eql?(sig.f_value) then
85
+ self.show_signal(sig)
86
+ shown_values[sig] = sig.f_value
87
+ end
88
+ end
89
+ # Clear the list of active signals.
90
+ @sig_active.clear
91
+ # puts "sig_exec.size=#{@sig_exec.size}"
92
+ # Execute the relevant behaviors and connections.
93
+ @sig_exec.each { |obj| obj.execute(:par) }
94
+ @sig_exec.clear
95
+ @sig_active.uniq! {|sig| sig.object_id }
96
+ # puts "@sig_active.size=#{@sig_active.size}"
97
+ # Advance time.
98
+ @time = (@timed_behaviors.min {|b0,b1| b0.time <=> b1.time }).time
99
+ end
100
+ # Display the time
101
+ self.show_time
102
+ end
103
+
39
104
  ## Run the simulation from the current systemT and outputs the resuts
40
105
  # on simout.
41
106
  def sim(simout)
@@ -43,20 +108,13 @@ module HDLRuby::High
43
108
  HDLRuby.show "#{Time.now}#{show_mem}"
44
109
  # Merge the included.
45
110
  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
111
  # Initializes the time.
56
112
  @time = 0
57
113
  # Initializes the time and signals execution buffers.
58
114
  @tim_exec = []
59
115
  @sig_exec = []
116
+ # Initilize the list of untimed objects.
117
+ @untimeds = []
60
118
  # Initialize the list of currently exisiting timed behavior.
61
119
  @timed_behaviors = []
62
120
  # Initialize the list of activated signals.
@@ -68,72 +126,97 @@ module HDLRuby::High
68
126
  self.init_sim(self)
69
127
  # Initialize the displayer.
70
128
  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
129
+
130
+ # Initialize the untimed objects.
131
+ self.init_untimeds
132
+ # puts "End of init_untimed."
133
+
134
+ # Is there more than one timed behavior.
135
+ if @total_timed_behaviors <= 1 then
136
+ # No, no need of multithreading.
137
+ @multithread = false
138
+ # Simple execute the block of the behavior.
139
+ @timed_behaviors[0].block.execute(:seq)
140
+ else
141
+ # Yes, need of multithreading.
142
+ @multithread = true
143
+ # Initializes the run mutex and the conditions.
144
+ @mutex = Mutex.new
145
+ @master = ConditionVariable.new
146
+ @master_flag = 0
147
+ @slave = ConditionVariable.new
148
+ @slave_flags_not = 0
149
+ @num_done = 0
150
+
151
+ # First all the timed behaviors are to be executed.
152
+ @timed_behaviors.each {|beh| @tim_exec << beh }
153
+ # But starts locked.
154
+ @slave_flags_not = 2**@timed_behaviors.size - 1
155
+ # Starts the threads.
156
+ @timed_behaviors.each {|beh| beh.make_thread }
157
+
158
+ HDLRuby.show "Starting Ruby-level simulator..."
159
+ HDLRuby.show "#{Time.now}#{show_mem}"
160
+ # Run the simulation.
161
+ self.run_init do
162
+ # # Wake the behaviors.
163
+ # @timed_behaviors.each {|beh| beh.run }
164
+ until @tim_exec.empty? do
165
+ # Execute the time behaviors that are ready.
166
+ self.run_ack
167
+ self.run_wait
168
+ # Advance the global simulator.
169
+ self.advance
170
+ # # Display the time
171
+ # self.show_time
172
+ # shown_values = {}
173
+ # # Get the behaviors waiting on activated signals.
174
+ # until @sig_active.empty? do
175
+ # # # Update the signals.
176
+ # # @sig_active.each { |sig| sig.c_value = sig.f_value }
177
+ # # puts "sig_active.size=#{@sig_active.size}"
178
+ # # Look for the behavior sensitive to the signals.
179
+ # @sig_active.each do |sig|
180
+ # sig.each_anyedge { |beh| @sig_exec << beh }
181
+ # if (sig.c_value.zero? && !sig.f_value.zero?) then
182
+ # # puts "sig.c_value=#{sig.c_value.content}"
183
+ # sig.each_posedge { |beh| @sig_exec << beh }
184
+ # elsif (!sig.c_value.zero? && sig.f_value.zero?) then
185
+ # sig.each_negedge { |beh| @sig_exec << beh }
186
+ # end
187
+ # end
188
+ # # Update the signals.
189
+ # @sig_active.each { |sig| sig.c_value = sig.f_value }
190
+ # # puts "first @sig_exec.size=#{@sig_exec.size}"
191
+ # @sig_exec.uniq! {|beh| beh.object_id }
192
+ # # Display the activated signals.
193
+ # @sig_active.each do |sig|
194
+ # if !shown_values[sig].eql?(sig.f_value) then
195
+ # self.show_signal(sig)
196
+ # shown_values[sig] = sig.f_value
197
+ # end
198
+ # end
199
+ # # Clear the list of active signals.
200
+ # @sig_active.clear
201
+ # # puts "sig_exec.size=#{@sig_exec.size}"
202
+ # # Execute the relevant behaviors and connections.
203
+ # @sig_exec.each { |obj| obj.execute(:par) }
204
+ # @sig_exec.clear
205
+ # @sig_active.uniq! {|sig| sig.object_id }
206
+ # # puts "@sig_active.size=#{@sig_active.size}"
207
+ # end
208
+
209
+ # # Advance time.
210
+ # @time = (@timed_behaviors.min {|b0,b1| b0.time <=> b1.time }).time
211
+ break if @timed_behaviors.empty?
212
+ # Schedule the next timed behavior to execute.
213
+ @tim_exec = []
214
+ @timed_behaviors.each do |beh|
215
+ @tim_exec << beh if beh.time == @time
117
216
  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}"
217
+ # puts "@tim_exec.size=#{@tim_exec.size}"
218
+ # puts "@timed_bevaviors.size=#{@timed_behaviors.size}"
126
219
  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
134
- end
135
- # puts "@tim_exec.size=#{@tim_exec.size}"
136
- # puts "@timed_bevaviors.size=#{@timed_behaviors.size}"
137
220
  end
138
221
  end
139
222
  end
@@ -146,6 +229,17 @@ module HDLRuby::High
146
229
  # Recure on the scope.
147
230
  self.scope.init_sim(systemT)
148
231
  end
232
+
233
+ ## Initialize the untimed objects.
234
+ def init_untimeds
235
+ @untimeds.each do |obj|
236
+ if obj.is_a?(Behavior) then
237
+ obj.block.execute(:seq)
238
+ else
239
+ obj.execute(:seq)
240
+ end
241
+ end
242
+ end
149
243
 
150
244
  ## Initialize run for executing +ruby_block+
151
245
  def run_init(&ruby_block)
@@ -278,6 +372,8 @@ module HDLRuby::High
278
372
 
279
373
  ## Initialize the simulation for system +systemT+.
280
374
  def init_sim(systemT)
375
+ # Add the behavior to the list of untimed objects.
376
+ systemT.add_untimed(self)
281
377
  # Process the sensitivity list.
282
378
  # Is it a clocked behavior?
283
379
  events = self.each_event.to_a
@@ -292,6 +388,7 @@ module HDLRuby::High
292
388
  end.to_a
293
389
  # Keep only one ref per signal.
294
390
  refs.uniq! { |node| node.fullname }
391
+ # puts "refs=#{refs.map {|node| node.fullname}}"
295
392
  # Remove the inner signals from the list.
296
393
  self.block.each_inner do |inner|
297
394
  refs.delete_if {|r| r.name == inner.name }
@@ -358,7 +455,8 @@ module HDLRuby::High
358
455
  begin
359
456
  # puts "Starting thread"
360
457
  systemT.run_req(@id)
361
- self.block.execute(:par)
458
+ # self.block.execute(:par)
459
+ self.block.execute(:seq)
362
460
  # puts "Ending thread"
363
461
  rescue => e
364
462
  puts "Got exception: #{e.full_message}"
@@ -456,8 +554,8 @@ module HDLRuby::High
456
554
  @f_value = value
457
555
  # Set the mode.
458
556
  @mode = mode
459
- # puts "assign #{value.content} (#{value.content.class}) with self.type.width=#{self.type.width} while value.type.width=#{value.type.width}" if self.name.to_s.include?("idx")
460
- # @f_value = value.cast(self.type) # Cast inserted by HDLRuby normally
557
+ # puts "assign #{value.content} (#{value.content.class}) with self.type.width=#{self.type.width} while value.type.width=#{value.type.width}" if self.name.to_s.include?("xnor")
558
+ @f_value = value.cast(self.type) # Cast not always inserted by HDLRuby normally
461
559
  end
462
560
 
463
561
  ## Assigns +value+ at +index+ (integer or range).
@@ -607,7 +705,7 @@ module HDLRuby::High
607
705
  ## Initialize the simulation for system +systemT+.
608
706
  def init_sim(systemT)
609
707
  self.each_when { |wh| wh.init_sim(systemT) }
610
- self.default.init_sim(systemT)
708
+ self.default.init_sim(systemT) if self.default
611
709
  end
612
710
 
613
711
  ## Executes the statement.
@@ -618,7 +716,7 @@ module HDLRuby::High
618
716
  return
619
717
  end
620
718
  end
621
- self.default.execute(mode)
719
+ self.default.execute(mode) if self.default
622
720
  end
623
721
  end
624
722
  end
@@ -690,10 +788,16 @@ module HDLRuby::High
690
788
  def execute(mode)
691
789
  @behavior ||= self.behavior
692
790
  @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)
791
+ if @sim.multithread then
792
+ # Multi thread mode: synchronize.
793
+ # puts "Stopping #{@behavior.object_id} (@behavior.time=#{@behavior.time})..."
794
+ @sim.run_done(@behavior.id)
795
+ # puts "Rerunning #{@behavior.object_id} (@behavior.time=#{@behavior.time})..."
796
+ @sim.run_req(@behavior.id)
797
+ else
798
+ # No thread mode, need to advance the global simulator.
799
+ @sim.advance
800
+ end
697
801
  end
698
802
  end
699
803
 
@@ -783,6 +887,8 @@ module HDLRuby::High
783
887
 
784
888
  ## Initialize the simulation for system +systemT+.
785
889
  def init_sim(systemT)
890
+ # Add the connection to the list of untimed objets.
891
+ systemT.add_untimed(self)
786
892
  # Recurse on the left.
787
893
  self.left.init_sim(systemT)
788
894
  # Process the sensitivity list.
@@ -795,6 +901,8 @@ module HDLRuby::High
795
901
  end.to_a
796
902
  # Keep only one ref per signal.
797
903
  refs.uniq! { |node| node.fullname }
904
+ # puts "connection input: #{self.left.fullname}"
905
+ # puts "connection refs=#{refs.map {|node| node.fullname}}"
798
906
  # # Generate the event.
799
907
  # events = refs.map {|ref| Event.new(:anyedge,ref) }
800
908
  # # Add them to the behavior for further processing.
@@ -806,7 +914,7 @@ module HDLRuby::High
806
914
 
807
915
  ## Executes the statement.
808
916
  def execute(mode)
809
- # puts "connection = #{self}"
917
+ # puts "connection = #{self}" if self.left.is_a?(RefObject) && self.left.object.name.to_s.include?("xnor")
810
918
  self.left.assign(mode,self.right.execute(mode))
811
919
  end
812
920
  end
@@ -906,10 +1014,18 @@ module HDLRuby::High
906
1014
  class Select
907
1015
  ## Execute the expression.
908
1016
  def execute(mode)
1017
+ unless @mask then
1018
+ # Need to initialize the execution of the select.
1019
+ width = (@choices.size-1).width
1020
+ width = 1 if width == 0
1021
+ @mask = 2**width - 1
1022
+ @choices.concat([@choices[-1]] * (2**width-@choices.size))
1023
+ end
909
1024
  # Recurse on the select.
910
- tmps = self.select.execute(mode)
1025
+ tmps = self.select.execute(mode).to_i & @mask
1026
+ # puts "select tmps=#{tmps}, @choices.size=#{@choices.size}"
911
1027
  # Recurse on the selection result.
912
- return @choices[tmps.to_i].execute(mode)
1028
+ return @choices[tmps].execute(mode)
913
1029
  end
914
1030
  end
915
1031
 
@@ -0,0 +1,35 @@
1
+ require "HDLRuby/hruby_rsim"
2
+
3
+ ##
4
+ # Library for enhancing the Ruby simulator with VCD support
5
+ #
6
+ ########################################################################
7
+ module HDLRuby::High
8
+
9
+ ##
10
+ # Enhance the system type class with VCD support.
11
+ class SystemT
12
+
13
+ ## Initializes the displayer for generating a vcd on +vcdout+
14
+ def show_init(vcdout)
15
+ end
16
+
17
+ ## Displays the time.
18
+ def show_time
19
+ end
20
+
21
+ ## Displays the value of signal +sig+.
22
+ def show_signal(sig)
23
+ end
24
+
25
+ ## Displays value +val+.
26
+ # NOTE: for now displays on the standard output and NOT the vcd.
27
+ def show_value(val)
28
+ end
29
+
30
+ ## Displays string +str+.
31
+ def show_string(str)
32
+ end
33
+ end
34
+
35
+ end