HDLRuby 2.11.3 → 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: 71e8ee2662101e18157249150f4766654b0c049e08c87190fa6e06e2805d087b
4
- data.tar.gz: cfc13c02e2fae3ad7d2a3831be9728cc35dffa3096016c2790d9649d19348f18
3
+ metadata.gz: 450d4465eb4fb71c70d61bdadf5bd0d944b5b8c7f7f9f3d02f847d670eb74f76
4
+ data.tar.gz: b3cf3b934d8a50f6d85ffc74f3a34b0cfd2f074d472d2f6a8b93b4324cc2e5bd
5
5
  SHA512:
6
- metadata.gz: cae45da4c41f556fc550a53272861e3def26bc15107a7bcb2cce1b3f8e99491d4b9cb8d2d4f4f621f422ef99c64ed704ac2e05a5f7c2b6d906133f420994aaf1
7
- data.tar.gz: d29fb9b5ba800bcc4dff27c78e8a5762b9e7be1550ec1cb916a3cda543fabce878cc317c11e208e7a299896a7fc308cb307db0667dc6b3f416920b3d1c5fa2b0
6
+ metadata.gz: 667da8c2f678834407374f739ea4d0094803e82145b1485aa2b53bcef54f04b368668ad62996aaa67ae48b0e80fb9c9c9f731131e3eeb6c69c5c23363b2242e7
7
+ data.tar.gz: 39ae4cea2c84140063b601b5c3f171462db40a41b01739894daa95b90cec6dd8c87780cc86f65ff269a0d7fb4478412d06c114d4c3a921ade691c6c3d9868110
data/README.md CHANGED
@@ -1949,15 +1949,19 @@ There are two kinds of such statements:
1949
1949
  !10.ns
1950
1950
  ```
1951
1951
 
1952
- - The `repeat` statements: such a statement takes as argument a time value and a block. The execution of the block is repeated until the delay that is given by the time value argument expires. For example, the following code executes repeatedly the inversion of the `clk` signal every 10 nanoseconds for 10 seconds (i.e., it simulates a clock signal for 10 seconds):
1952
+ - The `repeat` statements: such a statement takes as argument a number of iteration and a block. The execution of the block is repeated the given number times. For example, the following code executes 10 times the inversion of the `clk` signal every 10 nanoseconds:
1953
1953
 
1954
1954
  ```ruby
1955
- repeat(10.s) do
1955
+ repeat(10) do
1956
1956
  !10.ns
1957
1957
  clk <= ~clk
1958
1958
  end
1959
1959
  ```
1960
1960
 
1961
+ __Note:__
1962
+
1963
+ This statement is not synthesizable and therefore can only be used in timed behaviors.
1964
+
1961
1965
  ### Parallel and sequential execution
1962
1966
 
1963
1967
  Time behaviors are by default sequential, but they can include both parallel and
@@ -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;
@@ -430,6 +433,27 @@ VALUE rcsim_make_timeWait(VALUE mod, VALUE unitV, VALUE delayV) {
430
433
  return res;
431
434
  }
432
435
 
436
+ /* Creating a time repeat C object. */
437
+ VALUE rcsim_make_timeRepeat(VALUE mod, VALUE numberV, VALUE statementV) {
438
+ // printf("rcsim_make_timeRepeat\n"); fflush(stdout);
439
+ /* Allocates the time repeat. */
440
+ TimeRepeat timeRepeat = (TimeRepeat)malloc(sizeof(TimeRepeatS));
441
+ // printf("timeRepeat=%p\n",timeRepeat); fflush(stdout);
442
+ /* Set it up. */
443
+ timeRepeat->kind = TIME_REPEAT;
444
+ /* Get and set the number of repeatition. */
445
+ long long number;
446
+ number = NUM2LL(numberV);
447
+ // printf("number=%lld\n",number); fflush(stdout);
448
+ timeRepeat->number = number;
449
+ /* Get and set the statement. */
450
+ value_to_rcsim(StatementS,statementV,timeRepeat->statement);
451
+ /* Returns the C time wait embedded into a ruby VALUE. */
452
+ VALUE res;
453
+ rcsim_to_value(TimeRepeatS,timeRepeat,res);
454
+ return res;
455
+ }
456
+
433
457
 
434
458
  /* Creating a time terminate C object. */
435
459
  VALUE rcsim_make_timeTerminate(VALUE mod) {
@@ -447,19 +471,19 @@ VALUE rcsim_make_timeTerminate(VALUE mod) {
447
471
 
448
472
 
449
473
  /* Creating a hardware if C object. */
450
- VALUE rcsim_make_hif(VALUE mod, VALUE condition, VALUE yes, VALUE no) {
474
+ VALUE rcsim_make_hif(VALUE mod, VALUE conditionV, VALUE yesV, VALUE noV) {
451
475
  // printf("rcsim_make_hif\n");
452
476
  /* Allocates the hardware if. */
453
477
  HIf hif = (HIf)malloc(sizeof(HIfS));
454
478
  // printf("hif=%p\n",hif);
455
479
  /* Set it up. */
456
480
  hif->kind = HIF;
457
- value_to_rcsim(ExpressionS,condition,hif->condition);
458
- value_to_rcsim(StatementS,yes,hif->yes);
459
- if (TYPE(no) == T_NIL)
481
+ value_to_rcsim(ExpressionS,conditionV,hif->condition);
482
+ value_to_rcsim(StatementS,yesV,hif->yes);
483
+ if (TYPE(noV) == T_NIL)
460
484
  hif->no = NULL;
461
485
  else
462
- value_to_rcsim(StatementS,no,hif->no);
486
+ value_to_rcsim(StatementS,noV,hif->no);
463
487
  hif->num_noifs = 0;
464
488
  hif->noconds = NULL;
465
489
  hif->nostmnts = NULL;
@@ -471,21 +495,21 @@ VALUE rcsim_make_hif(VALUE mod, VALUE condition, VALUE yes, VALUE no) {
471
495
 
472
496
 
473
497
  /* Creating a hardware case C object. */
474
- VALUE rcsim_make_hcase(VALUE mod, VALUE value, VALUE defolt) {
498
+ VALUE rcsim_make_hcase(VALUE mod, VALUE valueV, VALUE defoltV) {
475
499
  // printf("rcsim_make_hcase\n");
476
500
  /* Allocates the hardware case. */
477
501
  HCase hcase = (HCase)malloc(sizeof(HCaseS));
478
502
  // printf("hcase=%p\n",hcase);
479
503
  /* Set it up. */
480
504
  hcase->kind = HCASE;
481
- value_to_rcsim(ExpressionS,value,hcase->value);
505
+ value_to_rcsim(ExpressionS,valueV,hcase->value);
482
506
  hcase->num_whens = 0;
483
507
  hcase->matches = NULL;
484
508
  hcase->stmnts = NULL;
485
- if (TYPE(defolt) == T_NIL)
509
+ if (TYPE(defoltV) == T_NIL)
486
510
  hcase->defolt = NULL;
487
511
  else
488
- value_to_rcsim(StatementS,defolt,hcase->defolt);
512
+ value_to_rcsim(StatementS,defoltV,hcase->defolt);
489
513
  /* Returns the C hardware case embedded into a ruby VALUE. */
490
514
  VALUE res;
491
515
  rcsim_to_value(HCaseS,hcase,res);
@@ -494,7 +518,7 @@ VALUE rcsim_make_hcase(VALUE mod, VALUE value, VALUE defolt) {
494
518
 
495
519
 
496
520
  /* Creating a block C object. */
497
- VALUE rcsim_make_block(VALUE mod, VALUE mode) {
521
+ VALUE rcsim_make_block(VALUE mod, VALUE modeV) {
498
522
  // printf("rcsim_make_block\n");
499
523
  /* Allocates the block. */
500
524
  Block block = (Block)malloc(sizeof(BlockS));
@@ -507,7 +531,7 @@ VALUE rcsim_make_block(VALUE mod, VALUE mode) {
507
531
  block->inners = NULL;
508
532
  block->num_stmnts = 0;
509
533
  block->stmnts = NULL;
510
- block->mode = SYM2ID(mode) == id_PAR ? PAR : SEQ;
534
+ block->mode = SYM2ID(modeV) == id_PAR ? PAR : SEQ;
511
535
  /* Returns the C block embedded into a ruby VALUE. */
512
536
  VALUE res;
513
537
  rcsim_to_value(BlockS,block,res);
@@ -1373,6 +1397,7 @@ void Init_hruby_sim() {
1373
1397
  rb_define_singleton_method(mod,"rcsim_make_transmit",rcsim_make_transmit,2);
1374
1398
  rb_define_singleton_method(mod,"rcsim_make_print",rcsim_make_print,0);
1375
1399
  rb_define_singleton_method(mod,"rcsim_make_timeWait",rcsim_make_timeWait,2);
1400
+ rb_define_singleton_method(mod,"rcsim_make_timeRepeat",rcsim_make_timeRepeat,2);
1376
1401
  rb_define_singleton_method(mod,"rcsim_make_timeTerminate",rcsim_make_timeTerminate,0);
1377
1402
  rb_define_singleton_method(mod,"rcsim_make_hif",rcsim_make_hif,3);
1378
1403
  rb_define_singleton_method(mod,"rcsim_make_hcase",rcsim_make_hcase,2);
@@ -28,6 +28,7 @@ typedef struct PrintS_ PrintS;
28
28
  typedef struct HIfS_ HIfS;
29
29
  typedef struct HCaseS_ HCaseS;
30
30
  typedef struct TimeWaitS_ TimeWaitS;
31
+ typedef struct TimeRepeatS_ TimeRepeatS;
31
32
  typedef struct TimeTerminateS_ TimeTerminateS;
32
33
  typedef struct ExpressionS_ ExpressionS;
33
34
  typedef struct UnaryS_ UnaryS;
@@ -63,6 +64,7 @@ typedef struct PrintS_* Print;
63
64
  typedef struct HIfS_* HIf;
64
65
  typedef struct HCaseS_* HCase;
65
66
  typedef struct TimeWaitS_* TimeWait;
67
+ typedef struct TimeRepeatS_* TimeRepeat;
66
68
  typedef struct TimeTerminateS_* TimeTerminate;
67
69
  typedef struct ExpressionS_* Expression;
68
70
  typedef struct UnaryS_* Unary;
@@ -89,7 +91,8 @@ typedef enum {
89
91
  #endif
90
92
  OBJECT, SYSTEMT, SIGNALI, SCOPE, BEHAVIOR, SYSTEMI, CODE, BLOCK, EVENT,
91
93
  #ifdef RCSIM
92
- /* Statements */ TRANSMIT, PRINT, HIF, HCASE, TIME_WAIT, TIME_TERMINATE,
94
+ /* Statements */ TRANSMIT, PRINT, HIF, HCASE,
95
+ TIME_WAIT, TIME_REPEAT, TIME_TERMINATE,
93
96
  /* Expressions */ UNARY, BINARY, SELECT, CONCAT, CAST,
94
97
  /* References */ REF_OBJECT, REF_INDEX, REF_RANGE, REF_CONCAT,
95
98
  /* Non-hardware*/ STRINGE,
@@ -521,6 +524,8 @@ typedef struct SignalIS_ {
521
524
  Object* pos; /* The objects actvated on pos edge. */
522
525
  int num_neg; /* The number of behavior activated on neg edge. */
523
526
  Object* neg; /* The objects actvated on neg edge. */
527
+
528
+ size_t id; /* The identity of the signal. */
524
529
  } SignalIS;
525
530
 
526
531
 
@@ -670,6 +675,13 @@ typedef struct TimeWaitS_ {
670
675
  unsigned long long delay; /* The delay to wait in pico seconds. */
671
676
  } TimeWaitS;
672
677
 
678
+ /** The C model of a time repeat statement. */
679
+ typedef struct TimeRepeatS_ {
680
+ Kind kind; /* The kind of object. */
681
+ long long number; /* The number of interations, negative means infinity. */
682
+ Statement statement;/* The statement to execute in loop. */
683
+ } TimeRepeatS;
684
+
673
685
  /** The C model of a time terminate statement. */
674
686
  typedef struct TimeTerminateS_ {
675
687
  Kind kind; /* The kind of object. */
@@ -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
 
@@ -358,6 +358,20 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) {
358
358
  hw_wait(delay,behavior);
359
359
  break;
360
360
  }
361
+ case TIME_REPEAT:
362
+ {
363
+ TimeRepeat rep = (TimeRepeat)stmnt;
364
+ if (rep->number>=0) {
365
+ for(long long i=0; i<rep->number; ++i) {
366
+ execute_statement(rep->statement,mode,behavior);
367
+ }
368
+ } else {
369
+ for(;;) {
370
+ execute_statement(rep->statement,mode,behavior);
371
+ }
372
+ }
373
+ break;
374
+ }
361
375
  case BLOCK:
362
376
  {
363
377
  Block block = (Block)stmnt;
@@ -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
  }
@@ -0,0 +1,48 @@
1
+ # A simple D-FF
2
+ system :dff do
3
+ input :d, :clk, :rst
4
+ output :q
5
+
6
+ (q <= d & ~rst).at(clk.posedge)
7
+ end
8
+
9
+ # A benchmark for the dff using repeat.
10
+ system :dff_bench do
11
+ inner :d, :clk, :rst
12
+ inner :q
13
+
14
+ dff(:my_dff).(d,clk,rst,q)
15
+
16
+ timed do
17
+ clk <= 0
18
+ rst <= 0
19
+ d <= _z
20
+ !10.ns
21
+ clk <= 1
22
+ rst <= 0
23
+ d <= _z
24
+ !10.ns
25
+ clk <= 0
26
+ rst <= 1
27
+ d <= _z
28
+ !10.ns
29
+ clk <= 1
30
+ rst <= 1
31
+ d <= _z
32
+ !10.ns
33
+ clk <= 0
34
+ rst <= 0
35
+ d <= 1
36
+ !10.ns
37
+ clk <= 1
38
+ rst <= 0
39
+ !10.ns
40
+ repeat(100) do
41
+ clk <= 0
42
+ d <= ~d
43
+ !10.ns
44
+ clk <= 1
45
+ !10.ns
46
+ end
47
+ end
48
+ end
@@ -2682,10 +2682,10 @@ module HDLRuby::High
2682
2682
 
2683
2683
  # Converts the repeat statement to HDLRuby::Low.
2684
2684
  def to_low
2685
- # return HDLRuby::Low::TimeRepeat.new(self.statement.to_low,
2685
+ # timeRepeatL = HDLRuby::Low::TimeRepeat.new(self.statement.to_low,
2686
2686
  # self.delay.to_low)
2687
- timeRepeatL = HDLRuby::Low::TimeRepeat.new(self.statement.to_low,
2688
- self.delay.to_low)
2687
+ timeRepeatL = HDLRuby::Low::TimeRepeat.new(self.number,
2688
+ self.statement.to_low)
2689
2689
  # # For debugging: set the source high object
2690
2690
  # timeRepeatL.properties[:low2high] = self.hdr_id
2691
2691
  # self.properties[:high2low] = timeRepeatL
@@ -4233,15 +4233,20 @@ module HDLRuby::High
4233
4233
  self.add_statement(TimeWait.new(delay))
4234
4234
  end
4235
4235
 
4236
- # Adds a loop until +delay+ statement in the block in +mode+ whose
4236
+ # # Adds a loop until +delay+ statement in the block in +mode+ whose
4237
+ # # loop content is built using +ruby_block+.
4238
+ # def repeat(delay, mode = nil, &ruby_block)
4239
+ # Adds a +number+ times loop statement in the block in +mode+ whose
4237
4240
  # loop content is built using +ruby_block+.
4238
- def repeat(delay, mode = nil, &ruby_block)
4241
+ # NOTE: if +number+ is negative, the number of iteration is infinite.
4242
+ def repeat(number = -1, mode = nil, &ruby_block)
4239
4243
  # Ensure there is a block.
4240
4244
  ruby_block = proc {} unless block_given?
4241
4245
  # Build the content block.
4242
4246
  content = High.make_block(mode,&ruby_block)
4243
4247
  # Create and add the statement.
4244
- self.add_statement(TimeRepeat.new(content,delay))
4248
+ # self.add_statement(TimeRepeat.new(content,delay))
4249
+ self.add_statement(TimeRepeat.new(number,content))
4245
4250
  end
4246
4251
 
4247
4252
  # Converts the time block to HDLRuby::Low.
@@ -4042,15 +4042,20 @@ module HDLRuby::Low
4042
4042
  ##
4043
4043
  # Describes a timed loop statement: not synthesizable!
4044
4044
  class TimeRepeat < Statement
4045
- # The delay until the loop is repeated
4046
- attr_reader :delay
4045
+ # # The delay until the loop is repeated
4046
+ # attr_reader :delay
4047
+ # The number of interrations.
4048
+ attr_reader :number
4047
4049
 
4048
4050
  # The statement to execute.
4049
4051
  attr_reader :statement
4050
4052
 
4051
- # Creates a new timed loop statement execute in a loop +statement+ until
4052
- # +delay+ has passed.
4053
- def initialize(statement,delay)
4053
+ # # Creates a new timed loop statement execute in a loop +statement+ until
4054
+ # # +delay+ has passed.
4055
+ # def initialize(statement,delay)
4056
+ # Creates a new timed loop statement execute in a loop +statement+
4057
+ # +number+ times (negative means inifinity).
4058
+ def initialize(number,statement)
4054
4059
  # Check and set the statement.
4055
4060
  unless statement.is_a?(Statement)
4056
4061
  raise AnyError,
@@ -4061,13 +4066,15 @@ module HDLRuby::Low
4061
4066
  # And set its parent.
4062
4067
  statement.parent = self
4063
4068
 
4064
- # Check and set the delay.
4065
- unless delay.is_a?(Delay)
4066
- raise AnyError, "Invalid class for a delay: #{delay.class}."
4067
- end
4068
- @delay = delay
4069
- # And set its parent.
4070
- delay.parent = self
4069
+ # # Check and set the delay.
4070
+ # unless delay.is_a?(Delay)
4071
+ # raise AnyError, "Invalid class for a delay: #{delay.class}."
4072
+ # end
4073
+ # @delay = delay
4074
+ # Check and set the number.
4075
+ @number = number.to_i
4076
+ # # And set its parent.
4077
+ # delay.parent = self
4071
4078
  end
4072
4079
 
4073
4080
  # Iterates over each object deeply.
@@ -4080,26 +4087,29 @@ module HDLRuby::Low
4080
4087
  ruby_block.call(self)
4081
4088
  # Then apply on the statement.
4082
4089
  self.statement.each_deep(&ruby_block)
4083
- # Then apply on the delay.
4084
- self.delay.each_deep(&ruby_block)
4090
+ # # Then apply on the delay.
4091
+ # self.delay.each_deep(&ruby_block)
4085
4092
  end
4086
4093
 
4087
4094
  # Comparison for hash: structural comparison.
4088
4095
  def eql?(obj)
4089
4096
  return false unless obj.is_a?(TimeRepeat)
4090
- return false unless @delay.eql?(obj.delay)
4097
+ # return false unless @delay.eql?(obj.delay)
4098
+ return false unless @number.eql?(obj.number)
4091
4099
  return false unless @statement.eql?(obj.statement)
4092
4100
  return true
4093
4101
  end
4094
4102
 
4095
4103
  # Hash function.
4096
4104
  def hash
4097
- return [@delay,@statement].hash
4105
+ # return [@delay,@statement].hash
4106
+ return [@number,@statement].hash
4098
4107
  end
4099
4108
 
4100
4109
  # Clones the TimeRepeat (deeply)
4101
4110
  def clone
4102
- return TimeRepeat.new(@statement.clone,@delay.clone)
4111
+ # return TimeRepeat.new(@statement.clone,@delay.clone)
4112
+ return TimeRepeat.new(@statement.clone,@number)
4103
4113
  end
4104
4114
 
4105
4115
  # Iterates over the expression children if any.