HDLRuby 2.10.5 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- 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. */
|