HDLRuby 2.11.4 → 2.11.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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