HDLRuby 2.11.4 → 2.11.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5b3303f28a79a14a42fb2421335afdbaa40c148440e622edaca2f8a98804192d
4
- data.tar.gz: 12dd7c5fd160141c151db950b7d797ef53bf012549ef983f8cf1b648edb3a85e
3
+ metadata.gz: 450d4465eb4fb71c70d61bdadf5bd0d944b5b8c7f7f9f3d02f847d670eb74f76
4
+ data.tar.gz: b3cf3b934d8a50f6d85ffc74f3a34b0cfd2f074d472d2f6a8b93b4324cc2e5bd
5
5
  SHA512:
6
- metadata.gz: 94ba5098e5e8003f64c53f86ba47f8e831e3e49d39aa4f8991f3595dfec560749079720a6602bf76f2e31eacf88c922a0c689bf575e2ec17a48256dba70010d0
7
- data.tar.gz: 1856330cc10987e979ed13211d3a6aaaa1f382bfe9a6831a4a235eac35ea912844c5ca9b667f2a899b87a47518c29e38cb8c9b7c6a5ee27e953872fb810b8f30
6
+ metadata.gz: 667da8c2f678834407374f739ea4d0094803e82145b1485aa2b53bcef54f04b368668ad62996aaa67ae48b0e80fb9c9c9f731131e3eeb6c69c5c23363b2242e7
7
+ data.tar.gz: 39ae4cea2c84140063b601b5c3f171462db40a41b01739894daa95b90cec6dd8c87780cc86f65ff269a0d7fb4478412d06c114d4c3a921ade691c6c3d9868110
@@ -299,11 +299,14 @@ VALUE rcsim_make_event(VALUE mod, VALUE typeV, VALUE sigV) {
299
299
  }
300
300
 
301
301
 
302
+ static size_t last_signal_id = 0;
303
+
302
304
  /* Creating a signal C object. */
303
305
  VALUE rcsim_make_signal(VALUE mod, VALUE name, VALUE type) {
304
306
  // printf("rcsim_make_signal\n");
305
307
  /* Allocates the signal. */
306
308
  SignalI signal = (SignalI)malloc(sizeof(SignalIS));
309
+ signal->id = last_signal_id++;
307
310
  // printf("signal=%p\n",signal);
308
311
  /* Set it up. */
309
312
  signal->kind = SIGNALI;
@@ -524,6 +524,8 @@ typedef struct SignalIS_ {
524
524
  Object* pos; /* The objects actvated on pos edge. */
525
525
  int num_neg; /* The number of behavior activated on neg edge. */
526
526
  Object* neg; /* The objects actvated on neg edge. */
527
+
528
+ size_t id; /* The identity of the signal. */
527
529
  } SignalIS;
528
530
 
529
531
 
@@ -62,7 +62,8 @@ static pthread_cond_t hruby_beh_cond = PTHREAD_COND_INITIALIZER;
62
62
  static pthread_cond_t hruby_sim_cond = PTHREAD_COND_INITIALIZER;
63
63
 
64
64
  /** Flags for the simulation. */
65
- static int sim_end_flag = 0;
65
+ static int sim_single_flag = 0; /* Run in single timed behavior mode. */
66
+ static int sim_end_flag = 0; /* Ending the simulation. */
66
67
 
67
68
  /** Adds a timed behavior for processing.
68
69
  * @param behavior the timed behavior to register */
@@ -422,6 +423,21 @@ void* behavior_run(void* arg) {
422
423
  pthread_exit(NULL);
423
424
  }
424
425
 
426
+ /** Starts a signle timed behavior to run without the multi-threaded engine. */
427
+ void hruby_sim_start_single_timed_behavior() {
428
+ int i;
429
+ // printf("hruby_sim_start_single_timed_behaviors\n");fflush(stdout);
430
+ /* Set in mono-thread mode. */
431
+ sim_single_flag = 1;
432
+ Behavior behavior = timed_behaviors[0];
433
+ /* Simply run the timed behavior. */
434
+ #ifdef RCSIM
435
+ execute_statement((Statement)(behavior->block),0,behavior);
436
+ #else
437
+ behavior->block->function();
438
+ #endif
439
+ }
440
+
425
441
 
426
442
  /** Starts the timed behaviors.
427
443
  * @note create a thread per timed behavior. */
@@ -473,37 +489,46 @@ void hruby_sim_core(char* name, void (*init_vizualizer)(char*),
473
489
  /* Initialize the time to 0. */
474
490
  hruby_sim_time = 0;
475
491
 
476
- /* Start all the timed behaviors. */
477
- hruby_sim_start_timed_behaviors();
478
- // /* Activate the timed behavior that are on time. */
479
- // hruby_sim_activate_behaviors_on_time();
480
-
481
- /* Run while there are active behaviors and the time limit is not
482
- * reached */
483
- while(hruby_sim_time<limit) {
484
- int i;
485
- // printf("num_active_behaviors = %d\n",num_active_behaviors);
486
- /* Wait for the active timed behaviors to perform their computations. */
487
- hruby_sim_wait_behaviors();
488
- /* Update the signal values (recursively executing blocks locked
489
- * on the signals). */
492
+ if (num_timed_behaviors == 1) {
493
+ /* Initialize and touch all the signals. */
490
494
  hruby_sim_update_signals();
491
- if (hruby_sim_time == 0) {
492
- /* Initially touch all the signals. */
493
- each_all_signal(&touch_signal);
494
- }
495
- // printf("num_run_behavior=%d\n",num_run_behaviors);
496
- if (num_run_behaviors <= 0) break;
497
- /* Advance time to next timestep. */
498
- hruby_sim_advance_time();
495
+ each_all_signal(&touch_signal);
496
+ /* Only one timed behavior, no need of the multi-threaded engine. */
497
+ hruby_sim_start_single_timed_behavior();
498
+ } else {
499
+ /* Use the multi-threaded engine. */
500
+ /* Start all the timed behaviors. */
501
+ hruby_sim_start_timed_behaviors();
502
+ // /* Activate the timed behavior that are on time. */
503
+ // hruby_sim_activate_behaviors_on_time();
504
+
505
+ /* Run while there are active behaviors and the time limit is not
506
+ * reached */
507
+ while(hruby_sim_time<limit) {
508
+ int i;
509
+ // printf("num_active_behaviors = %d\n",num_active_behaviors);
510
+ /* Wait for the active timed behaviors to perform their computations. */
511
+ hruby_sim_wait_behaviors();
512
+ /* Update the signal values (recursively executing blocks locked
513
+ * on the signals). */
514
+ hruby_sim_update_signals();
515
+ if (hruby_sim_time == 0) {
516
+ /* Initially touch all the signals. */
517
+ each_all_signal(&touch_signal);
518
+ }
519
+ // printf("num_run_behavior=%d\n",num_run_behaviors);
520
+ if (num_run_behaviors <= 0) break;
521
+ /* Advance time to next timestep. */
522
+ hruby_sim_advance_time();
523
+
524
+ /* Mark the signals as fading. */
525
+ for(i=0; i<num_all_signals; ++i) {
526
+ all_signals[i]->fading = 1;
527
+ }
499
528
 
500
- /* Mark the signals as fading. */
501
- for(i=0; i<num_all_signals; ++i) {
502
- all_signals[i]->fading = 1;
529
+ /* Activate the timed behavior that are on time. */
530
+ hruby_sim_activate_behaviors_on_time();
503
531
  }
504
-
505
- /* Activate the timed behavior that are on time. */
506
- hruby_sim_activate_behaviors_on_time();
507
532
  }
508
533
  }
509
534
 
@@ -521,29 +546,38 @@ void hruby_sim_core(char* name, void (*init_vizualizer)(char*),
521
546
  * @param delay the delay to wait in ps.
522
547
  * @param behavior the current behavior. */
523
548
  void hw_wait(unsigned long long delay, Behavior behavior) {
524
- /* Maybe the thread is to end immediatly. */
525
- if (sim_end_flag)
526
- pthread_exit(NULL);
527
- /* No go on with the wait procedure. */
528
- pthread_mutex_lock(&hruby_sim_mutex);
529
- /* Indicate the behavior finished current execution. */
530
- num_active_behaviors -= 1;
531
- // printf("!!num_active_behaviors=%d\n",num_active_behaviors);
532
- // pthread_cond_signal(&hruby_sim_cond);
533
- /* Update the behavior's time. */
534
- behavior->active_time += delay;
535
- pthread_mutex_unlock(&hruby_sim_mutex);
536
- pthread_cond_signal(&hruby_sim_cond);
537
- /* Wait for being reactivated. */
538
- while(behavior->active_time > hruby_sim_time) {
549
+ /* Is it in single timed behavior mode? */
550
+ if (sim_single_flag) {
551
+ /* Yes, simply update signals and advance time. */
552
+ behavior->active_time += delay;
553
+ hruby_sim_update_signals();
554
+ hruby_sim_advance_time();
555
+ } else {
556
+ /* No, handle the multi-threading. */
557
+ /* Maybe the thread is to end immediatly. */
558
+ if (sim_end_flag)
559
+ pthread_exit(NULL);
560
+ /* No go on with the wait procedure. */
539
561
  pthread_mutex_lock(&hruby_sim_mutex);
540
- while(!behaviors_can_run) {
541
- // printf("!1\n");
542
- // pthread_cond_wait(&compute_cond, &hruby_sim_mutex);
543
- pthread_cond_wait(&hruby_beh_cond, &hruby_sim_mutex);
544
- // printf("!2\n");
545
- }
562
+ /* Indicate the behavior finished current execution. */
563
+ num_active_behaviors -= 1;
564
+ // printf("!!num_active_behaviors=%d\n",num_active_behaviors);
565
+ // pthread_cond_signal(&hruby_sim_cond);
566
+ /* Update the behavior's time. */
567
+ behavior->active_time += delay;
546
568
  pthread_mutex_unlock(&hruby_sim_mutex);
569
+ pthread_cond_signal(&hruby_sim_cond);
570
+ /* Wait for being reactivated. */
571
+ while(behavior->active_time > hruby_sim_time) {
572
+ pthread_mutex_lock(&hruby_sim_mutex);
573
+ while(!behaviors_can_run) {
574
+ // printf("!1\n");
575
+ // pthread_cond_wait(&compute_cond, &hruby_sim_mutex);
576
+ pthread_cond_wait(&hruby_beh_cond, &hruby_sim_mutex);
577
+ // printf("!2\n");
578
+ }
579
+ pthread_mutex_unlock(&hruby_sim_mutex);
580
+ }
547
581
  }
548
582
  }
549
583
 
@@ -98,7 +98,6 @@ static void vcd_print_name(Object object) {
98
98
  * @param object the object to print the name. */
99
99
  static void vcd_print_full_name(Object object) {
100
100
  /* Recurse on the owner if any. */
101
- // printf("owner=%p\n",object->owner);
102
101
  if (object->owner != NULL) {
103
102
  vcd_print_full_name(object->owner);
104
103
  vcd_print("$");
@@ -107,12 +106,23 @@ static void vcd_print_full_name(Object object) {
107
106
  vcd_print_name(object);
108
107
  }
109
108
 
109
+ /** Prints the id of a signal in vcd indentifier format.
110
+ * @param signal the signal to print the id. */
111
+ static void vcd_print_signal_id(SignalI signal) {
112
+ size_t id = signal->id;
113
+ do {
114
+ vcd_print("%c",(id % (127-33)) + 33);
115
+ id = id / (127-33);
116
+ } while (id > 0);
117
+ }
118
+
110
119
  /** Prints a value.
111
120
  * @param value the value to print */
112
121
  static void vcd_print_value(Value value) {
113
- vcd_print("b");
122
+ unsigned long long width = type_width(value->type);
123
+ if (width > 1) vcd_print("b");
114
124
  if (value->numeric) {
115
- unsigned long long width = type_width(value->type);
125
+ // unsigned long long width = type_width(value->type);
116
126
  unsigned long long mask = 1ULL << (width-1);
117
127
  for(; mask > 0; mask >>= 1) {
118
128
  vcd_print("%d",(value->data_int & mask) != 0);
@@ -120,7 +130,7 @@ static void vcd_print_value(Value value) {
120
130
  } else {
121
131
  /* Display a bitstring value. */
122
132
  unsigned long long i;
123
- unsigned long long width = type_width(value->type);
133
+ // unsigned long long width = type_width(value->type);
124
134
  char* data = value->data_str;
125
135
  if (value->capacity == 0) {
126
136
  /* The value is empty, therefore undefined. */
@@ -135,13 +145,15 @@ static void vcd_print_value(Value value) {
135
145
  }
136
146
  }
137
147
  }
148
+ if (width > 1) vcd_print(" ");
138
149
  }
139
150
 
140
151
  /** Prints a signal declaration.
141
152
  * @param signal the signal to declare */
142
153
  static void vcd_print_var(SignalI signal) {
143
154
  vcd_print("$var wire %d ",type_width(signal->type));
144
- vcd_print_full_name((Object)signal);
155
+ // vcd_print_full_name((Object)signal);
156
+ vcd_print_signal_id(signal);
145
157
  vcd_print(" ");
146
158
  vcd_print_name((Object)signal);
147
159
  vcd_print(" $end\n");
@@ -153,8 +165,9 @@ static void vcd_print_var(SignalI signal) {
153
165
  static void vcd_print_signal_fvalue(SignalI signal) {
154
166
  if (signal->f_value) {
155
167
  vcd_print_value(signal->f_value);
156
- vcd_print(" ");
157
- vcd_print_full_name((Object)signal);
168
+ // vcd_print(" ");
169
+ // vcd_print_full_name((Object)signal);
170
+ vcd_print_signal_id(signal);
158
171
  vcd_print("\n");
159
172
  }
160
173
  }
@@ -165,8 +178,9 @@ static void vcd_print_signal_fvalue(SignalI signal) {
165
178
  static void vcd_print_signal_cvalue(SignalI signal) {
166
179
  if (signal->c_value) {
167
180
  vcd_print_value(signal->c_value);
168
- vcd_print(" ");
169
- vcd_print_full_name((Object)signal);
181
+ // vcd_print(" ");
182
+ // vcd_print_full_name((Object)signal);
183
+ vcd_print_signal_id(signal);
170
184
  vcd_print("\n");
171
185
  }
172
186
  }
@@ -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"
@@ -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
 
@@ -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,11 @@ 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
180
258
  end
181
259
 
182
260
  ##
@@ -192,6 +270,11 @@ module HDLRuby::High
192
270
  def get_vars_with_fullname(vars_with_fullname = {})
193
271
  # By default: nothing to do
194
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
195
278
  end
196
279
 
197
280
  ##
@@ -206,6 +289,11 @@ module HDLRuby::High
206
289
  def get_vars_with_fullname(vars_with_fullname = {})
207
290
  # By default: nothing to do
208
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
209
297
  end
210
298
 
211
299
  ##
@@ -220,6 +308,11 @@ module HDLRuby::High
220
308
  def get_vars_with_fullname(vars_with_fullname = {})
221
309
  # By default: nothing to do
222
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
223
316
  end
224
317
 
225
318
 
@@ -238,7 +331,8 @@ module HDLRuby::High
238
331
  self.each_inner do |sig|
239
332
  # puts "showing inner signal #{HDLRuby::High.vcd_name(sig.fullname)}"
240
333
  vcdout << "$var wire #{sig.type.width} "
241
- vcdout << "#{HDLRuby::High.vcd_name(sig.fullname)} "
334
+ # vcdout << "#{HDLRuby::High.vcd_name(sig.fullname)} "
335
+ vcdout << "#{HDLRuby::High.vcd_idstr(sig)} "
242
336
  vcdout << "#{HDLRuby::High.vcd_name(sig.name)} $end\n"
243
337
  end
244
338
  # Recurse on the statements
@@ -263,6 +357,19 @@ module HDLRuby::High
263
357
  end
264
358
  return vars_with_fullname
265
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
266
373
  end
267
374
 
268
375
 
@@ -307,6 +414,19 @@ module HDLRuby::High
307
414
  self.no.get_vars_with_fullname(vars_with_fullname) if self.no
308
415
  return vars_with_fullname
309
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
310
430
  end
311
431
 
312
432
 
@@ -333,5 +453,41 @@ module HDLRuby::High
333
453
  self.default.get_vars_with_fullname(vars_with_fullname)
334
454
  return vars_with_fullname
335
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
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
336
491
  end
492
+
337
493
  end
@@ -1,3 +1,3 @@
1
1
  module HDLRuby
2
- VERSION = "2.11.4"
2
+ VERSION = "2.11.5"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: HDLRuby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.11.4
4
+ version: 2.11.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lovic Gauthier
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-11 00:00:00.000000000 Z
11
+ date: 2022-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler