HDLRuby 2.11.4 → 2.11.7

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.
@@ -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