HDLRuby 2.11.3 → 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: 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.