HDLRuby 2.10.5 → 2.11.0
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 +4 -4
- data/HDLRuby.gemspec +1 -0
- data/README.md +8 -4
- data/Rakefile +8 -0
- data/{lib/HDLRuby/sim/Makefile → ext/hruby_sim/Makefile_csim} +0 -0
- data/ext/hruby_sim/extconf.rb +13 -0
- data/ext/hruby_sim/hruby_rcsim_build.c +1188 -0
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim.h +255 -16
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_calc.c +310 -181
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_core.c +34 -17
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_list.c +0 -0
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_stack_calc.c +4 -1
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_stack_calc.c.sav +0 -0
- data/ext/hruby_sim/hruby_sim_tree_calc.c +375 -0
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_vcd.c +5 -5
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_vizualize.c +2 -2
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_value_pool.c +4 -1
- data/lib/HDLRuby/hdr_samples/bstr_bench.rb +2 -0
- data/lib/HDLRuby/hdr_samples/case_bench.rb +2 -2
- data/lib/HDLRuby/hdr_samples/counter_bench.rb +0 -1
- data/lib/HDLRuby/hdr_samples/counter_dff_bench.rb +46 -0
- data/lib/HDLRuby/hdr_samples/dff_bench.rb +1 -1
- data/lib/HDLRuby/hdr_samples/print_bench.rb +62 -0
- data/lib/HDLRuby/hdr_samples/rom.rb +5 -3
- data/lib/HDLRuby/hdr_samples/simple_counter_bench.rb +43 -0
- data/lib/HDLRuby/hdrcc.rb +54 -8
- data/lib/HDLRuby/hruby_bstr.rb +1175 -917
- data/lib/HDLRuby/hruby_high.rb +200 -90
- data/lib/HDLRuby/hruby_high_fullname.rb +82 -0
- data/lib/HDLRuby/hruby_low.rb +41 -23
- data/lib/HDLRuby/hruby_low2c.rb +7 -0
- data/lib/HDLRuby/hruby_rcsim.rb +978 -0
- data/lib/HDLRuby/hruby_rsim.rb +1134 -0
- data/lib/HDLRuby/hruby_rsim_vcd.rb +322 -0
- data/lib/HDLRuby/hruby_values.rb +362 -18
- data/lib/HDLRuby/hruby_verilog.rb +21 -3
- data/lib/HDLRuby/version.rb +1 -1
- metadata +24 -13
@@ -67,6 +67,7 @@ static int sim_end_flag = 0;
|
|
67
67
|
/** Adds a timed behavior for processing.
|
68
68
|
* @param behavior the timed behavior to register */
|
69
69
|
void register_timed_behavior(Behavior behavior) {
|
70
|
+
// printf("Registering timed behavior=%p\n",behavior);fflush(stdout);
|
70
71
|
if (num_timed_behaviors == cap_timed_behaviors) {
|
71
72
|
if (cap_timed_behaviors == 0) {
|
72
73
|
/* Need to create the array containing the timed behaviors. */
|
@@ -100,7 +101,7 @@ void register_signal(SignalI signal) {
|
|
100
101
|
all_signals=new_signals;
|
101
102
|
}
|
102
103
|
}
|
103
|
-
/* Add the
|
104
|
+
/* Add the signal. */
|
104
105
|
all_signals[num_all_signals++] = signal;
|
105
106
|
}
|
106
107
|
|
@@ -108,15 +109,16 @@ void register_signal(SignalI signal) {
|
|
108
109
|
/** Recursively update the signals until no (untimed) behavior are
|
109
110
|
* activated. */
|
110
111
|
void hruby_sim_update_signals() {
|
111
|
-
|
112
|
+
// printf("hruby_sim_update_signals...\n");fflush(stdout);
|
112
113
|
/* As long as the list of touched signals is not empty go on computing. */
|
113
114
|
while(!empty_list(touched_signals) || !empty_list(touched_signals_seq)) {
|
114
|
-
// printf("## Checking touched signals.\n");
|
115
|
+
// printf("## Checking touched signals.\n");fflush(stdout);
|
115
116
|
/* Sets the new signals values and mark the signals as activating. */
|
116
117
|
/* For the case of the parallel execution model. */
|
117
118
|
while(!empty_list(touched_signals)) {
|
118
119
|
Elem e = remove_list(touched_signals);
|
119
120
|
SignalI sig = e->data;
|
121
|
+
// printf("sig=%p kind=%d\n",sig,sig->kind);fflush(stdout);
|
120
122
|
delete_element(e);
|
121
123
|
/* Is there a change? */
|
122
124
|
if (same_content_value(sig->c_value,sig->f_value)) continue;
|
@@ -124,7 +126,7 @@ void hruby_sim_update_signals() {
|
|
124
126
|
printer.print_signal(sig);
|
125
127
|
// printf("c_value="); printer.print_value(sig->c_value);
|
126
128
|
// printf("\nf_value="); printer.print_value(sig->f_value); printf("\n");
|
127
|
-
// printf("Touched signal: %p (%s)\n",sig,sig->name);
|
129
|
+
// printf("Touched signal: %p (%s)\n",sig,sig->name);fflush(stdout);
|
128
130
|
/* Update the current value of the signal. */
|
129
131
|
copy_value(sig->f_value,sig->c_value);
|
130
132
|
// /* Mark the signal as activated. */
|
@@ -148,11 +150,13 @@ void hruby_sim_update_signals() {
|
|
148
150
|
}
|
149
151
|
/* Positive edge activation. */
|
150
152
|
if (!zero_value(sig->c_value)) {
|
153
|
+
// printf("PAR: posedge for sig=%s with num_pos=%i\n",sig->name,sig->num_pos);
|
151
154
|
for(i=0; i<sig->num_pos; ++i) {
|
152
155
|
Object obj = sig->pos[i];
|
153
156
|
if (obj->kind == BEHAVIOR) {
|
154
157
|
/* Behavior case. */
|
155
158
|
Behavior beh = (Behavior)obj;
|
159
|
+
// printf("Activating beh=%p.\n",beh);
|
156
160
|
beh->activated = 1;
|
157
161
|
add_list(activate_codes,get_element(beh));
|
158
162
|
} else {
|
@@ -210,6 +214,7 @@ void hruby_sim_update_signals() {
|
|
210
214
|
}
|
211
215
|
/* Positive edge activation. */
|
212
216
|
if (!zero_value(sig->c_value)) {
|
217
|
+
// printf("SEQ: posedge for sig=%s with num_pos=%i\n",sig->name,sig->num_pos);
|
213
218
|
for(i=0; i<sig->num_pos; ++i) {
|
214
219
|
Object obj = sig->pos[i];
|
215
220
|
if (obj->kind == BEHAVIOR) {
|
@@ -253,10 +258,17 @@ void hruby_sim_update_signals() {
|
|
253
258
|
if (obj->kind == BEHAVIOR) {
|
254
259
|
/* Behavior case. */
|
255
260
|
Behavior beh = (Behavior)obj;
|
261
|
+
// printf("beh=%p\n",beh);
|
256
262
|
/* Is the code really enabled and activated? */
|
257
263
|
if (beh->enabled && beh->activated) {
|
258
264
|
/* Yes, execute it. */
|
265
|
+
#ifdef RCSIM
|
266
|
+
// printf("going to execute with beh=%p\n",beh);
|
267
|
+
// printf("going to execute: %p with kind=%d\n",beh->block,beh->block->kind);
|
268
|
+
execute_statement((Statement)(beh->block),0,beh);
|
269
|
+
#else
|
259
270
|
beh->block->function();
|
271
|
+
#endif
|
260
272
|
/* And deactivate it. */
|
261
273
|
beh->activated = 0;
|
262
274
|
}
|
@@ -284,9 +296,11 @@ void hruby_sim_advance_time() {
|
|
284
296
|
int i;
|
285
297
|
for(i=0; i<num_timed_behaviors; ++i) {
|
286
298
|
unsigned long long beh_time = timed_behaviors[i]->active_time;
|
299
|
+
// printf("beh_time=%llu\n",beh_time);
|
287
300
|
if (timed_behaviors[i]->timed == 1)
|
288
301
|
if (beh_time < next_time) next_time = beh_time;
|
289
302
|
}
|
303
|
+
// printf("hruby_sim_time=%llu next_time=%llu\n",hruby_sim_time,next_time);
|
290
304
|
/* Sets the new activation time. */
|
291
305
|
hruby_sim_time = next_time;
|
292
306
|
// println_time(hruby_sim_time);
|
@@ -294,7 +308,7 @@ void hruby_sim_advance_time() {
|
|
294
308
|
}
|
295
309
|
|
296
310
|
|
297
|
-
/** Sets the
|
311
|
+
/** Sets the enable status of the behaviors of a scope.
|
298
312
|
* @param scope the scope to process.
|
299
313
|
* @param status the enable status. */
|
300
314
|
static void set_enable_scope(Scope scope, int status) {
|
@@ -334,7 +348,6 @@ void activate_behavior(Behavior behavior) {
|
|
334
348
|
* time. */
|
335
349
|
void hruby_sim_activate_behaviors_on_time() {
|
336
350
|
int i;
|
337
|
-
// printf("$1\n");
|
338
351
|
pthread_mutex_lock(&hruby_sim_mutex);
|
339
352
|
/* Count the number of behaviors that will be activated. */
|
340
353
|
for(i=0; i<num_timed_behaviors; ++i) {
|
@@ -349,7 +362,6 @@ void hruby_sim_activate_behaviors_on_time() {
|
|
349
362
|
}
|
350
363
|
/* Activate the behaviors .*/
|
351
364
|
behaviors_can_run = 1;
|
352
|
-
// printf("$2\n");
|
353
365
|
// pthread_cond_signal(&compute_cond); /* No behaviors. */
|
354
366
|
// pthread_cond_signal(&hruby_beh_cond);
|
355
367
|
pthread_mutex_unlock(&hruby_sim_mutex);
|
@@ -361,14 +373,12 @@ void hruby_sim_activate_behaviors_on_time() {
|
|
361
373
|
void hruby_sim_wait_behaviors() {
|
362
374
|
pthread_mutex_lock(&hruby_sim_mutex);
|
363
375
|
while(num_active_behaviors > 0) {
|
364
|
-
// printf("$3\n");
|
365
376
|
// printf("num_active_behaviors = %d\n",num_active_behaviors);
|
366
377
|
// pthread_cond_wait(&active_behaviors_cond, &hruby_sim_mutex);
|
367
378
|
pthread_cond_wait(&hruby_sim_cond, &hruby_sim_mutex);
|
368
379
|
}
|
369
380
|
behaviors_can_run = 0;
|
370
381
|
pthread_mutex_unlock(&hruby_sim_mutex);
|
371
|
-
// printf("$4\n");
|
372
382
|
}
|
373
383
|
|
374
384
|
|
@@ -377,7 +387,6 @@ void hruby_sim_wait_behaviors() {
|
|
377
387
|
void* behavior_run(void* arg) {
|
378
388
|
Behavior behavior = (Behavior)arg;
|
379
389
|
/* First lock the behavior until the simulation engine starts. */
|
380
|
-
// printf("#1\n");
|
381
390
|
pthread_mutex_lock(&hruby_sim_mutex);
|
382
391
|
num_active_behaviors -= 1;
|
383
392
|
while(!behaviors_can_run) {
|
@@ -386,11 +395,16 @@ void* behavior_run(void* arg) {
|
|
386
395
|
pthread_cond_wait(&hruby_beh_cond, &hruby_sim_mutex);
|
387
396
|
}
|
388
397
|
pthread_mutex_unlock(&hruby_sim_mutex);
|
389
|
-
// printf("#2\n");
|
390
398
|
/* Now can start the execution of the behavior. */
|
391
|
-
if (behavior->enabled)
|
399
|
+
if (behavior->enabled) {
|
400
|
+
#ifdef RCSIM
|
401
|
+
// printf("going to execute with behavior=%p\n",behavior);
|
402
|
+
// printf("going to execute: %p with kind=%d\n",behavior->block,behavior->block->kind);
|
403
|
+
execute_statement((Statement)(behavior->block),0,behavior);
|
404
|
+
#else
|
392
405
|
behavior->block->function();
|
393
|
-
|
406
|
+
#endif
|
407
|
+
}
|
394
408
|
/* Now can start the execution of the behavior. */
|
395
409
|
/* Stops the behavior. */
|
396
410
|
pthread_mutex_lock(&hruby_sim_mutex);
|
@@ -410,6 +424,8 @@ void* behavior_run(void* arg) {
|
|
410
424
|
* @note create a thread per timed behavior. */
|
411
425
|
void hruby_sim_start_timed_behaviors() {
|
412
426
|
int i;
|
427
|
+
// printf("hruby_sim_start_timed_behaviors\n");fflush(stdout);
|
428
|
+
// printf("timed_behaviors=%p\n",timed_behaviors);fflush(stdout);
|
413
429
|
pthread_mutex_lock(&hruby_sim_mutex);
|
414
430
|
/* Sets the end flags to 0. */
|
415
431
|
sim_end_flag = 0;
|
@@ -418,12 +434,11 @@ void hruby_sim_start_timed_behaviors() {
|
|
418
434
|
/* Create and start the threads. */
|
419
435
|
for(i=0; i<num_timed_behaviors; ++i) {
|
420
436
|
num_run_behaviors += 1;
|
421
|
-
// ++num_active_behaviors;
|
422
|
-
// printf("0 num_run_behaviors = %d\n",num_run_behaviors);
|
423
437
|
pthread_create(&timed_behaviors[i]->thread,NULL,
|
424
438
|
&behavior_run,timed_behaviors[i]);
|
425
439
|
}
|
426
440
|
pthread_mutex_unlock(&hruby_sim_mutex);
|
441
|
+
// exit(0);
|
427
442
|
}
|
428
443
|
|
429
444
|
/** Ends waiting all the threads properly terminates. */
|
@@ -474,6 +489,7 @@ void hruby_sim_core(char* name, void (*init_vizualizer)(char*),
|
|
474
489
|
/* Initially touch all the signals. */
|
475
490
|
each_all_signal(&touch_signal);
|
476
491
|
}
|
492
|
+
// printf("num_run_behavior=%d\n",num_run_behaviors);
|
477
493
|
if (num_run_behaviors <= 0) break;
|
478
494
|
/* Advance time to next timestep. */
|
479
495
|
hruby_sim_advance_time();
|
@@ -499,7 +515,7 @@ void hruby_sim_core(char* name, void (*init_vizualizer)(char*),
|
|
499
515
|
|
500
516
|
|
501
517
|
/** Makes the behavior wait for a given time.
|
502
|
-
* @param delay the delay to wait in
|
518
|
+
* @param delay the delay to wait in ps.
|
503
519
|
* @param behavior the current behavior. */
|
504
520
|
void hw_wait(unsigned long long delay, Behavior behavior) {
|
505
521
|
/* Maybe the thread is to end immediatly. */
|
@@ -544,7 +560,6 @@ void touch_signal(SignalI signal) {
|
|
544
560
|
* @param value the value to transmit
|
545
561
|
* @param signal the signal to transmit the value to. */
|
546
562
|
void transmit_to_signal(Value value, SignalI signal) {
|
547
|
-
// printf("Tansmit to signal: %s(%p) with fading=%d\n",signal->name,signal,signal->fading);
|
548
563
|
/* Copy the content. */
|
549
564
|
if (signal->fading)
|
550
565
|
signal->f_value = copy_value(value,signal->f_value);
|
@@ -584,6 +599,7 @@ void transmit_to_signal_range(Value value, RefRangeS ref) {
|
|
584
599
|
* @param signal the signal to touch */
|
585
600
|
void touch_signal_seq(SignalI signal) {
|
586
601
|
// printf("touching signal seq: %p\n",signal);
|
602
|
+
// printf("signal->c_value=%p\n",signal->c_value);
|
587
603
|
/* Is there a difference between the present and future value? */
|
588
604
|
if (same_content_value(signal->c_value,signal->f_value)) return;
|
589
605
|
/* Yes, add the signal to the list of touched sequential ones and update
|
@@ -601,6 +617,7 @@ void touch_signal_seq(SignalI signal) {
|
|
601
617
|
* @param signal the signal to transmit the value to. */
|
602
618
|
void transmit_to_signal_seq(Value value, SignalI signal) {
|
603
619
|
// printf("Tansmit to signal seq: %s(%p)\n",signal->name,signal);
|
620
|
+
// printf("signal->f_value=%p\n",signal->f_value);
|
604
621
|
/* Copy the content. */
|
605
622
|
if (signal->fading)
|
606
623
|
copy_value(value,signal->f_value);
|
File without changes
|
@@ -1,3 +1,6 @@
|
|
1
|
+
/* Not used for the C-Ruby hybrid simulator. */
|
2
|
+
#ifndef RCSIM
|
3
|
+
|
1
4
|
#include <stdio.h>
|
2
5
|
#include <stdarg.h>
|
3
6
|
#include <stdlib.h>
|
@@ -5,7 +8,6 @@
|
|
5
8
|
#include <limits.h>
|
6
9
|
#include "hruby_sim.h"
|
7
10
|
|
8
|
-
|
9
11
|
/**
|
10
12
|
* The HDLRuby simulation stack calculation engine, to be used with C code
|
11
13
|
* generated by hruby_low2c.
|
@@ -248,3 +250,4 @@ void transmitR_seq(RefRangeS ref) {
|
|
248
250
|
transmit_to_signal_range_seq(pop(),ref);
|
249
251
|
}
|
250
252
|
|
253
|
+
#endif
|
File without changes
|
@@ -0,0 +1,375 @@
|
|
1
|
+
/* Used by the C-Ruby hybrid simulator only. */
|
2
|
+
#ifdef RCSIM
|
3
|
+
|
4
|
+
#include "extconf.h"
|
5
|
+
|
6
|
+
#include <stdio.h>
|
7
|
+
#include <stdarg.h>
|
8
|
+
#include <stdlib.h>
|
9
|
+
#include <string.h>
|
10
|
+
#include <limits.h>
|
11
|
+
#include "hruby_sim.h"
|
12
|
+
|
13
|
+
|
14
|
+
/**
|
15
|
+
* The HDLRuby simulation tree-based calculation engine.
|
16
|
+
**/
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
/** Calculates a tree expression.
|
21
|
+
* @param expr the expression to execute.
|
22
|
+
* @param res the expression where to write the result. */
|
23
|
+
Value calc_expression(Expression expr, Value res) {
|
24
|
+
// printf("calc_expression with kind=%d\n",expr->kind);
|
25
|
+
/* Depending on the kind of expression. */
|
26
|
+
switch(expr->kind) {
|
27
|
+
case VALUEE:
|
28
|
+
/* Assume it is a Value. */
|
29
|
+
// printf("value=%p type=%p\n",expr,((Value)expr)->type);
|
30
|
+
res = (Value)expr;
|
31
|
+
// res = copy_value((Value)expr,res);
|
32
|
+
break;
|
33
|
+
case UNARY:
|
34
|
+
{
|
35
|
+
Unary uexpr = (Unary)expr;
|
36
|
+
Value child = get_value();
|
37
|
+
child = calc_expression(uexpr->child,child);
|
38
|
+
res = uexpr->oper(child,res);
|
39
|
+
free_value();
|
40
|
+
break;
|
41
|
+
}
|
42
|
+
case BINARY:
|
43
|
+
{
|
44
|
+
Binary bexpr = (Binary)expr;
|
45
|
+
Value left = get_value();
|
46
|
+
Value right = get_value();
|
47
|
+
left = calc_expression(bexpr->left,left);
|
48
|
+
right = calc_expression(bexpr->right,right);
|
49
|
+
res = bexpr->oper(left,right,res);
|
50
|
+
free_value();
|
51
|
+
free_value();
|
52
|
+
break;
|
53
|
+
}
|
54
|
+
case CONCAT:
|
55
|
+
{
|
56
|
+
Concat cexpr = (Concat)expr;
|
57
|
+
/* Calculate the sub expressions. */
|
58
|
+
Value values[cexpr->num_exprs];
|
59
|
+
for(int i=0; i<cexpr->num_exprs; ++i) {
|
60
|
+
values[i] = get_value();
|
61
|
+
values[i] = calc_expression(cexpr->exprs[i],values[i]);
|
62
|
+
}
|
63
|
+
/* Use them for calculating the concat. */
|
64
|
+
res = concat_valueP(cexpr->num_exprs,cexpr->dir,res,values);
|
65
|
+
for(int i=0; i<cexpr->num_exprs; ++i) free_value();
|
66
|
+
break;
|
67
|
+
}
|
68
|
+
case CAST:
|
69
|
+
{
|
70
|
+
Cast cexpr = (Cast)expr;
|
71
|
+
Value child = get_value();
|
72
|
+
child = calc_expression(cexpr->child,child);
|
73
|
+
res = cast_value(child,cexpr->type,res);
|
74
|
+
free_value();
|
75
|
+
break;
|
76
|
+
}
|
77
|
+
case REF_OBJECT:
|
78
|
+
res = calc_expression((Expression)(((RefObject)expr)->object),res);
|
79
|
+
break;
|
80
|
+
case REF_INDEX:
|
81
|
+
{
|
82
|
+
RefIndex rexpr = (RefIndex)expr;
|
83
|
+
/* Compute the accessed value. */
|
84
|
+
Value value = get_value();
|
85
|
+
value = calc_expression((Expression)(rexpr->ref),value);
|
86
|
+
/* Compute the index. */
|
87
|
+
Value indexV = get_value();
|
88
|
+
indexV = calc_expression(rexpr->index,indexV);
|
89
|
+
/* Get its integer index. */
|
90
|
+
long long index = value2integer(indexV);
|
91
|
+
// printf("index=%llu\n",index);
|
92
|
+
free_value();
|
93
|
+
/* Performs the access. */
|
94
|
+
res = read_range(value,index,index,rexpr->type,res);
|
95
|
+
free_value();
|
96
|
+
break;
|
97
|
+
}
|
98
|
+
case REF_RANGE:
|
99
|
+
{
|
100
|
+
RefRangeE rexpr = (RefRangeE)expr;
|
101
|
+
/* Compute the accessed value. */
|
102
|
+
Value value = get_value();
|
103
|
+
value = calc_expression((Expression)(rexpr->ref),value);
|
104
|
+
/* Compute the range. */
|
105
|
+
Value firstV = get_value();
|
106
|
+
firstV = calc_expression(rexpr->first,firstV);
|
107
|
+
Value lastV = get_value();
|
108
|
+
lastV = calc_expression(rexpr->last,lastV);
|
109
|
+
/* Get its integer range. */
|
110
|
+
long long first = value2integer(firstV);
|
111
|
+
long long last = value2integer(lastV);
|
112
|
+
free_value();
|
113
|
+
free_value();
|
114
|
+
// printf("first=%lli last=%lli\n",first,last);
|
115
|
+
/* Performs the access. */
|
116
|
+
TypeS base_type = { rexpr->type->base, 1, rexpr->type->flags };
|
117
|
+
res = read_range(value,first,last,&base_type,res);
|
118
|
+
free_value();
|
119
|
+
break;
|
120
|
+
}
|
121
|
+
case REF_CONCAT:
|
122
|
+
{
|
123
|
+
RefConcat rexpr = (RefConcat)expr;
|
124
|
+
/* Process like a simple concat. */
|
125
|
+
/* Calculate the sub expressions. */
|
126
|
+
Value values[rexpr->num_refs];
|
127
|
+
for(int i=0; i<rexpr->num_refs; ++i) {
|
128
|
+
values[i] = get_value();
|
129
|
+
values[i] = calc_expression((Expression)(rexpr->refs[i]),values[i]);
|
130
|
+
}
|
131
|
+
/* Use them for calculating the concat. */
|
132
|
+
res = concat_valueP(rexpr->num_refs,rexpr->dir,res,values);
|
133
|
+
for(int i=0; i<rexpr->num_refs; ++i) free_value();
|
134
|
+
break;
|
135
|
+
}
|
136
|
+
case SIGNALI:
|
137
|
+
res = calc_expression((Expression)(((SignalI)expr)->c_value),res);
|
138
|
+
break;
|
139
|
+
default:
|
140
|
+
perror("Invalid expression kind.");
|
141
|
+
exit(1);
|
142
|
+
break;
|
143
|
+
}
|
144
|
+
return res;
|
145
|
+
}
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
/** Executes a statement.
|
150
|
+
* @param stmnt the statement to execute.
|
151
|
+
* @param mode blocking mode: 0: par, 1:seq
|
152
|
+
* @param behavior the behavior in execution. */
|
153
|
+
void execute_statement(Statement stmnt, int mode, Behavior behavior) {
|
154
|
+
/* Depending on the kind of statement. */
|
155
|
+
// printf("Executing statement=%p with kind=%d\n",stmnt,stmnt->kind);fflush(stdout);
|
156
|
+
switch(stmnt->kind) {
|
157
|
+
case TRANSMIT:
|
158
|
+
{
|
159
|
+
Transmit trans = (Transmit)stmnt;
|
160
|
+
// printf("trans=%p trans->left=%p trans->left->kind=%d\n",trans,trans->left,trans->left->kind);
|
161
|
+
/* Compute the right value. */
|
162
|
+
// Value right = calc_expression(trans->right);
|
163
|
+
Value right = get_value();
|
164
|
+
right = calc_expression(trans->right,right);
|
165
|
+
/* Depending on the left value. */
|
166
|
+
switch (trans->left->kind) {
|
167
|
+
case SIGNALI:
|
168
|
+
// printf("left->name=%s\n",((SignalI)(trans->left))->name);
|
169
|
+
fflush(stdout);
|
170
|
+
/* Simple transmission. */
|
171
|
+
if (mode)
|
172
|
+
transmit_to_signal_seq(right,(SignalI)(trans->left));
|
173
|
+
else
|
174
|
+
transmit_to_signal(right,(SignalI)(trans->left));
|
175
|
+
break;
|
176
|
+
case REF_INDEX:
|
177
|
+
{
|
178
|
+
/* Transmission to sub element. */
|
179
|
+
RefIndex refi = (RefIndex)(trans->left);
|
180
|
+
/* Compute the index. */
|
181
|
+
// Value indexV = calc_expression(refi->index);
|
182
|
+
Value indexV = get_value();
|
183
|
+
indexV = calc_expression(refi->index,indexV);
|
184
|
+
long long index = value2integer(indexV);
|
185
|
+
free_value();
|
186
|
+
/* Generate the reference inside the left value. */
|
187
|
+
RefRangeS ref =
|
188
|
+
make_ref_rangeS((SignalI)(refi->ref),refi->type,
|
189
|
+
index,index);
|
190
|
+
/* Perform the transmit. */
|
191
|
+
if(mode)
|
192
|
+
transmit_to_signal_range_seq(right,ref);
|
193
|
+
else
|
194
|
+
transmit_to_signal_range(right,ref);
|
195
|
+
break;
|
196
|
+
}
|
197
|
+
case REF_RANGE:
|
198
|
+
{
|
199
|
+
/* Transmission to range of sub elements. */
|
200
|
+
RefRangeE refr = (RefRangeE)(trans->left);
|
201
|
+
/* Compute the range. */
|
202
|
+
// Value firstV = calc_expression(refr->first);
|
203
|
+
Value firstV = get_value();
|
204
|
+
firstV = calc_expression(refr->first,firstV);
|
205
|
+
long long first = value2integer(firstV);
|
206
|
+
free_value();
|
207
|
+
// Value lastV = calc_expression(refr->last);
|
208
|
+
Value lastV = get_value();
|
209
|
+
lastV = calc_expression(refr->last,lastV);
|
210
|
+
long long last = value2integer(lastV);
|
211
|
+
free_value();
|
212
|
+
/* Generate the reference inside the left value. */
|
213
|
+
RefRangeS ref =
|
214
|
+
make_ref_rangeS((SignalI)(refr->ref),refr->type,
|
215
|
+
first,last);
|
216
|
+
/* Perform the transmit. */
|
217
|
+
if(mode)
|
218
|
+
transmit_to_signal_range_seq(right,ref);
|
219
|
+
else
|
220
|
+
transmit_to_signal_range(right,ref);
|
221
|
+
break;
|
222
|
+
}
|
223
|
+
case REF_CONCAT:
|
224
|
+
{
|
225
|
+
/* Transmit to each sub-reference. */
|
226
|
+
RefConcat refc = (RefConcat)(trans->left);
|
227
|
+
/* For that purpose use a temporary Transmit node. */
|
228
|
+
TransmitS subtrans = { TRANSMIT, NULL, NULL };
|
229
|
+
long long pos=0; /* The current position in the value
|
230
|
+
to assign */
|
231
|
+
/* For each sub reference. */
|
232
|
+
for(int i=0; i < refc->num_refs; ++i) {
|
233
|
+
/* Set up the transmit. */
|
234
|
+
subtrans.left = refc->refs[i];
|
235
|
+
long long size = type_width(subtrans.left->type);
|
236
|
+
subtrans.right = (Expression)get_value();
|
237
|
+
subtrans.right = (Expression)read_range(
|
238
|
+
right,pos,pos+size-1,
|
239
|
+
get_type_bit(),(Value)(subtrans.right));
|
240
|
+
/* Execute it. */
|
241
|
+
execute_statement((Statement)&subtrans,
|
242
|
+
mode,behavior);
|
243
|
+
/* Prepare the next step. */
|
244
|
+
free_value();
|
245
|
+
pos += size;
|
246
|
+
}
|
247
|
+
}
|
248
|
+
default:
|
249
|
+
perror("Invalid kind for a reference.");
|
250
|
+
}
|
251
|
+
break;
|
252
|
+
}
|
253
|
+
case PRINT:
|
254
|
+
{
|
255
|
+
Print prt = (Print)stmnt;
|
256
|
+
/* Prints each argument. */
|
257
|
+
for(int i=0; i<prt->num_args; ++i) {
|
258
|
+
Expression arg=prt->args[i];
|
259
|
+
switch(arg->kind) {
|
260
|
+
case SYSTEMT:
|
261
|
+
case SYSTEMI:
|
262
|
+
printer.print_string_name((Object)arg);
|
263
|
+
break;
|
264
|
+
case STRINGE:
|
265
|
+
printer.print_string(((StringE)arg)->str);
|
266
|
+
break;
|
267
|
+
default:
|
268
|
+
{
|
269
|
+
Value res = get_value();
|
270
|
+
res = calc_expression(arg,res);
|
271
|
+
printer.print_string_value(res);
|
272
|
+
free_value();
|
273
|
+
}
|
274
|
+
}
|
275
|
+
}
|
276
|
+
break;
|
277
|
+
}
|
278
|
+
case HIF:
|
279
|
+
{
|
280
|
+
HIf hif = (HIf)stmnt;
|
281
|
+
/* Calculation the condition. */
|
282
|
+
// Value condition = calc_expression(hif->condition);
|
283
|
+
Value condition = get_value();
|
284
|
+
condition = calc_expression(hif->condition,condition);
|
285
|
+
/* Is it true? */
|
286
|
+
if (is_defined_value(condition) && value2integer(condition)) {
|
287
|
+
/* Yes, execute the yes branch. */
|
288
|
+
execute_statement(hif->yes,mode,behavior);
|
289
|
+
} else {
|
290
|
+
/* No, maybe an alternate condition is met. */
|
291
|
+
int met = 0;/* Tell if an alternate condition has been met.*/
|
292
|
+
for(int i=0; i<hif->num_noifs; ++i) {
|
293
|
+
// Value subcond = calc_expression(hif->noconds[i]);
|
294
|
+
Value subcond = get_value();
|
295
|
+
subcond = calc_expression(hif->noconds[i],subcond);
|
296
|
+
if (is_defined_value(subcond) && value2integer(subcond)){
|
297
|
+
/* The subcondition is met, execute the corresponding
|
298
|
+
* substatement. */
|
299
|
+
execute_statement(hif->nostmnts[i],mode,behavior);
|
300
|
+
/* And remember it. */
|
301
|
+
met = 1;
|
302
|
+
free_value();
|
303
|
+
break;
|
304
|
+
}
|
305
|
+
free_value();
|
306
|
+
}
|
307
|
+
/* Where there a sub condition met? */
|
308
|
+
if (!met) {
|
309
|
+
/* No, execute the no statement. */
|
310
|
+
execute_statement(hif->no,mode,behavior);
|
311
|
+
}
|
312
|
+
}
|
313
|
+
free_value();
|
314
|
+
break;
|
315
|
+
}
|
316
|
+
case HCASE:
|
317
|
+
{
|
318
|
+
HCase hcase = (HCase)stmnt;
|
319
|
+
/* Calculation the value to check. */
|
320
|
+
// Value value = calc_expression(hcase->value);
|
321
|
+
Value value = get_value();
|
322
|
+
value = calc_expression(hcase->value,value);
|
323
|
+
/* Tell if a case if matched. */
|
324
|
+
int met = 0;
|
325
|
+
/* Check each case. */
|
326
|
+
Value cmp = get_value();
|
327
|
+
for(int i=0; i<hcase->num_whens; ++i) {
|
328
|
+
// cmp = equal_value_c(value,calc_expression(hcase->matches[i]),
|
329
|
+
// cmp);
|
330
|
+
Value match = get_value();
|
331
|
+
match = calc_expression(hcase->matches[i],match);
|
332
|
+
cmp = equal_value_c(value,match,cmp);
|
333
|
+
if (is_defined_value(cmp) && value2integer(cmp)) {
|
334
|
+
/* Found the right case, execute the corresponding
|
335
|
+
* statement. */
|
336
|
+
execute_statement(hcase->stmnts[i],mode,behavior);
|
337
|
+
/* And remeber it. */
|
338
|
+
met = 1;
|
339
|
+
free_value();
|
340
|
+
break;
|
341
|
+
}
|
342
|
+
free_value();
|
343
|
+
}
|
344
|
+
free_value();
|
345
|
+
free_value();
|
346
|
+
/* Was no case found and is there a default statement? */
|
347
|
+
if (!met && hcase->defolt) {
|
348
|
+
/* Yes, execute the default statement. */
|
349
|
+
execute_statement(hcase->defolt,mode,behavior);
|
350
|
+
}
|
351
|
+
break;
|
352
|
+
}
|
353
|
+
case TIME_WAIT:
|
354
|
+
{
|
355
|
+
/* Get the value of the delay. */
|
356
|
+
long long delay = ((TimeWait)stmnt)->delay;
|
357
|
+
/* Wait the given delay. */
|
358
|
+
hw_wait(delay,behavior);
|
359
|
+
break;
|
360
|
+
}
|
361
|
+
case BLOCK:
|
362
|
+
{
|
363
|
+
Block block = (Block)stmnt;
|
364
|
+
/* Execute each statement of the block. */
|
365
|
+
for(int i=0; i<block->num_stmnts; ++i)
|
366
|
+
execute_statement(block->stmnts[i],block->mode,behavior);
|
367
|
+
break;
|
368
|
+
}
|
369
|
+
|
370
|
+
default:
|
371
|
+
perror("Invalid kind for an expression.");
|
372
|
+
}
|
373
|
+
}
|
374
|
+
|
375
|
+
#endif
|
@@ -22,7 +22,7 @@ static unsigned long long vcd_timeunit = 1;
|
|
22
22
|
|
23
23
|
/** Prints to the vcd file.
|
24
24
|
* @param fmt the format for handling the variadic arguments. */
|
25
|
-
static int vcd_print(char* fmt, ...) {
|
25
|
+
static int vcd_print(const char* fmt, ...) {
|
26
26
|
int ret;
|
27
27
|
|
28
28
|
/* Declare a va_list type variable */
|
@@ -94,7 +94,7 @@ static void vcd_print_name(Object object) {
|
|
94
94
|
}
|
95
95
|
|
96
96
|
|
97
|
-
/** Prints the name of an object incluing its
|
97
|
+
/** Prints the name of an object incluing its hierarchy.
|
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. */
|
@@ -119,8 +119,8 @@ static void vcd_print_value(Value value) {
|
|
119
119
|
}
|
120
120
|
} else {
|
121
121
|
/* Display a bitstring value. */
|
122
|
-
|
123
|
-
|
122
|
+
unsigned long long i;
|
123
|
+
unsigned long long width = type_width(value->type);
|
124
124
|
char* data = value->data_str;
|
125
125
|
if (value->capacity == 0) {
|
126
126
|
/* The value is empty, therefore undefined. */
|
@@ -289,7 +289,6 @@ static void vcd_print_systemT_content(SystemT system) {
|
|
289
289
|
/** Prints the hierarchy of a system type.
|
290
290
|
* @param system the system to print. */
|
291
291
|
static void vcd_print_systemT(SystemT system) {
|
292
|
-
int i;
|
293
292
|
/* Declares the module. */
|
294
293
|
vcd_print("$scope module ");
|
295
294
|
vcd_print_name((Object)system);
|
@@ -346,6 +345,7 @@ static void vcd_print_header() {
|
|
346
345
|
|
347
346
|
/* The declaration of the hierarchy and the variables
|
348
347
|
* from the top system. */
|
348
|
+
// printf("top_system=%p\n",top_system);
|
349
349
|
vcd_print_systemT(top_system);
|
350
350
|
/* Ends the declarations. */
|
351
351
|
vcd_print("$enddefinitions $end\n");
|
@@ -89,8 +89,8 @@ void default_print_value(Value value) {
|
|
89
89
|
}
|
90
90
|
} else {
|
91
91
|
/* Display a bitstring value. */
|
92
|
-
|
93
|
-
|
92
|
+
unsigned long long i;
|
93
|
+
unsigned long long width = type_width(value->type);
|
94
94
|
char* data = value->data_str;
|
95
95
|
if (value->capacity == 0) {
|
96
96
|
/* The value is empty, therefore undefined. */
|