HDLRuby 2.11.4 → 2.11.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/hruby_sim/hruby_rcsim_build.c +87 -48
- data/ext/hruby_sim/hruby_sim.h +67 -1
- data/ext/hruby_sim/hruby_sim_calc.c +211 -28
- data/ext/hruby_sim/hruby_sim_core.c +140 -52
- data/ext/hruby_sim/hruby_sim_mute.c +65 -0
- data/ext/hruby_sim/hruby_sim_stack_calc.c +10 -0
- data/ext/hruby_sim/hruby_sim_tree_calc.c +36 -9
- data/ext/hruby_sim/hruby_sim_vcd.c +41 -23
- data/lib/HDLRuby/hdr_samples/arith_bench.rb +92 -0
- data/lib/HDLRuby/hdr_samples/constant_prop_bench.rb +58 -0
- data/lib/HDLRuby/hdrcc.rb +15 -6
- data/lib/HDLRuby/hruby_bstr.rb +15 -3
- data/lib/HDLRuby/hruby_high.rb +8 -4
- data/lib/HDLRuby/hruby_low.rb +14 -5
- data/lib/HDLRuby/hruby_low2c.rb +184 -68
- data/lib/HDLRuby/hruby_low_without_connection.rb +6 -2
- data/lib/HDLRuby/hruby_rcsim.rb +25 -15
- data/lib/HDLRuby/hruby_rsim.rb +201 -85
- data/lib/HDLRuby/hruby_rsim_mute.rb +35 -0
- data/lib/HDLRuby/hruby_rsim_vcd.rb +168 -12
- data/lib/HDLRuby/hruby_values.rb +19 -2
- data/lib/HDLRuby/hruby_verilog.rb +67 -17
- data/lib/HDLRuby/std/fsm.rb +3 -3
- data/lib/HDLRuby/version.rb +1 -1
- metadata +6 -2
@@ -35,6 +35,15 @@ static List touched_signals_seq = &touched_signals_seq_content;
|
|
35
35
|
static ListS activate_codes_content = { NULL, NULL };
|
36
36
|
static List activate_codes = &activate_codes_content;
|
37
37
|
|
38
|
+
|
39
|
+
/** The number of behavior to run for initialization (not the timed ones!). */
|
40
|
+
static int num_init_behaviors = 0;
|
41
|
+
/** The capacity of teh behavior to run for initialization. */
|
42
|
+
static int cap_init_behaviors = 0;
|
43
|
+
/** The behaviors to run for initialization (not the timed ones!). */
|
44
|
+
static Behavior* init_behaviors = 0;
|
45
|
+
|
46
|
+
|
38
47
|
/** The number of timed behaviors. */
|
39
48
|
static int num_timed_behaviors = 0;
|
40
49
|
/** The capacity of the timed behaviors. */
|
@@ -62,7 +71,8 @@ static pthread_cond_t hruby_beh_cond = PTHREAD_COND_INITIALIZER;
|
|
62
71
|
static pthread_cond_t hruby_sim_cond = PTHREAD_COND_INITIALIZER;
|
63
72
|
|
64
73
|
/** Flags for the simulation. */
|
65
|
-
static int
|
74
|
+
static int sim_single_flag = 0; /* Run in single timed behavior mode. */
|
75
|
+
static int sim_end_flag = 0; /* Ending the simulation. */
|
66
76
|
|
67
77
|
/** Adds a timed behavior for processing.
|
68
78
|
* @param behavior the timed behavior to register */
|
@@ -87,12 +97,33 @@ void register_timed_behavior(Behavior behavior) {
|
|
87
97
|
}
|
88
98
|
|
89
99
|
|
100
|
+
/** Adds a behavior for initialization (not timed!).
|
101
|
+
* @param beh the behavior to register. */
|
102
|
+
void register_init_behavior(Behavior beh) {
|
103
|
+
if (num_init_behaviors == cap_init_behaviors) {
|
104
|
+
if (cap_init_behaviors == 0) {
|
105
|
+
/* Need to create the array containing the behaviors. */
|
106
|
+
cap_init_behaviors = 100;
|
107
|
+
init_behaviors = calloc(cap_init_behaviors,sizeof(Behavior));
|
108
|
+
} else {
|
109
|
+
/* Need to increase the capacity. */
|
110
|
+
Behavior* new_behs = calloc(cap_init_behaviors*2,sizeof(Behavior));
|
111
|
+
memcpy(new_behs,init_behaviors,sizeof(Behavior[cap_init_behaviors]));
|
112
|
+
cap_init_behaviors *= 2;
|
113
|
+
init_behaviors=new_behs;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
/* Add the behavior. */
|
117
|
+
init_behaviors[num_init_behaviors++] = beh;
|
118
|
+
}
|
119
|
+
|
120
|
+
|
90
121
|
/** Adds a signal for global processing.
|
91
122
|
* @param signal the signal to register */
|
92
123
|
void register_signal(SignalI signal) {
|
93
124
|
if (num_all_signals == cap_all_signals) {
|
94
125
|
if (cap_all_signals == 0) {
|
95
|
-
/* Need to create the array containing the
|
126
|
+
/* Need to create the array containing the signals. */
|
96
127
|
cap_all_signals = 100;
|
97
128
|
all_signals = calloc(cap_all_signals,sizeof(SignalI));
|
98
129
|
} else {
|
@@ -109,6 +140,24 @@ void register_signal(SignalI signal) {
|
|
109
140
|
}
|
110
141
|
|
111
142
|
|
143
|
+
|
144
|
+
/** Initial run of the behaviors to init. */
|
145
|
+
void run_init_behaviors() {
|
146
|
+
int i;
|
147
|
+
for(i = 0; i<num_init_behaviors; ++i) {
|
148
|
+
Behavior beh = init_behaviors[i];
|
149
|
+
#ifdef RCSIM
|
150
|
+
// printf("Going to initialize behavior=%p with block=%p\n",beh,beh->block);fflush(stdout);
|
151
|
+
execute_statement((Statement)(beh->block),0,beh);
|
152
|
+
#else
|
153
|
+
beh->block->function();
|
154
|
+
#endif
|
155
|
+
}
|
156
|
+
}
|
157
|
+
|
158
|
+
|
159
|
+
|
160
|
+
|
112
161
|
/** Recursively update the signals until no (untimed) behavior are
|
113
162
|
* activated. */
|
114
163
|
void hruby_sim_update_signals() {
|
@@ -303,6 +352,8 @@ void hruby_sim_advance_time() {
|
|
303
352
|
if (timed_behaviors[i]->timed == 1)
|
304
353
|
if (beh_time < next_time) next_time = beh_time;
|
305
354
|
}
|
355
|
+
/* Mark again all the signals as fading. */
|
356
|
+
for(i=0; i<num_all_signals; ++i) all_signals[i]->fading = 1;
|
306
357
|
// printf("hruby_sim_time=%llu next_time=%llu\n",hruby_sim_time,next_time);
|
307
358
|
/* Sets the new activation time. */
|
308
359
|
hruby_sim_time = next_time;
|
@@ -422,6 +473,20 @@ void* behavior_run(void* arg) {
|
|
422
473
|
pthread_exit(NULL);
|
423
474
|
}
|
424
475
|
|
476
|
+
/** Starts a signle timed behavior to run without the multi-threaded engine. */
|
477
|
+
void hruby_sim_start_single_timed_behavior() {
|
478
|
+
// printf("hruby_sim_start_single_timed_behaviors\n");fflush(stdout);
|
479
|
+
/* Set in mono-thread mode. */
|
480
|
+
sim_single_flag = 1;
|
481
|
+
Behavior behavior = timed_behaviors[0];
|
482
|
+
/* Simply run the timed behavior. */
|
483
|
+
#ifdef RCSIM
|
484
|
+
execute_statement((Statement)(behavior->block),0,behavior);
|
485
|
+
#else
|
486
|
+
behavior->block->function();
|
487
|
+
#endif
|
488
|
+
}
|
489
|
+
|
425
490
|
|
426
491
|
/** Starts the timed behaviors.
|
427
492
|
* @note create a thread per timed behavior. */
|
@@ -473,37 +538,51 @@ void hruby_sim_core(char* name, void (*init_vizualizer)(char*),
|
|
473
538
|
/* Initialize the time to 0. */
|
474
539
|
hruby_sim_time = 0;
|
475
540
|
|
476
|
-
|
477
|
-
|
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). */
|
541
|
+
if (num_timed_behaviors == 1) {
|
542
|
+
/* Initialize and touch all the signals. */
|
490
543
|
hruby_sim_update_signals();
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
/*
|
498
|
-
|
544
|
+
// each_all_signal(&touch_signal);
|
545
|
+
run_init_behaviors();
|
546
|
+
/* Only one timed behavior, no need of the multi-threaded engine. */
|
547
|
+
hruby_sim_start_single_timed_behavior();
|
548
|
+
} else {
|
549
|
+
/* Use the multi-threaded engine. */
|
550
|
+
/* Initialize and touch all the signals. */
|
551
|
+
hruby_sim_update_signals();
|
552
|
+
// each_all_signal(&touch_signal);
|
553
|
+
run_init_behaviors();
|
554
|
+
/* Start all the timed behaviors. */
|
555
|
+
hruby_sim_start_timed_behaviors();
|
556
|
+
// /* Activate the timed behavior that are on time. */
|
557
|
+
// hruby_sim_activate_behaviors_on_time();
|
558
|
+
|
559
|
+
/* Run while there are active behaviors and the time limit is not
|
560
|
+
* reached */
|
561
|
+
while(hruby_sim_time<limit) {
|
562
|
+
int i;
|
563
|
+
// printf("num_active_behaviors = %d\n",num_active_behaviors);
|
564
|
+
/* Wait for the active timed behaviors to perform their computations. */
|
565
|
+
hruby_sim_wait_behaviors();
|
566
|
+
/* Update the signal values (recursively executing blocks locked
|
567
|
+
* on the signals). */
|
568
|
+
hruby_sim_update_signals();
|
569
|
+
if (hruby_sim_time == 0) {
|
570
|
+
/* Initially touch all the signals. */
|
571
|
+
each_all_signal(&touch_signal);
|
572
|
+
}
|
573
|
+
// printf("num_run_behavior=%d\n",num_run_behaviors);
|
574
|
+
if (num_run_behaviors <= 0) break;
|
575
|
+
/* Advance time to next timestep. */
|
576
|
+
hruby_sim_advance_time();
|
577
|
+
|
578
|
+
/* Mark the signals as fading. */
|
579
|
+
for(i=0; i<num_all_signals; ++i) {
|
580
|
+
all_signals[i]->fading = 1;
|
581
|
+
}
|
499
582
|
|
500
|
-
|
501
|
-
|
502
|
-
all_signals[i]->fading = 1;
|
583
|
+
/* Activate the timed behavior that are on time. */
|
584
|
+
hruby_sim_activate_behaviors_on_time();
|
503
585
|
}
|
504
|
-
|
505
|
-
/* Activate the timed behavior that are on time. */
|
506
|
-
hruby_sim_activate_behaviors_on_time();
|
507
586
|
}
|
508
587
|
}
|
509
588
|
|
@@ -521,29 +600,38 @@ void hruby_sim_core(char* name, void (*init_vizualizer)(char*),
|
|
521
600
|
* @param delay the delay to wait in ps.
|
522
601
|
* @param behavior the current behavior. */
|
523
602
|
void hw_wait(unsigned long long delay, Behavior behavior) {
|
524
|
-
/*
|
525
|
-
if (
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
pthread_cond_signal(&hruby_sim_cond);
|
537
|
-
/* Wait for being reactivated. */
|
538
|
-
while(behavior->active_time > hruby_sim_time) {
|
603
|
+
/* Is it in single timed behavior mode? */
|
604
|
+
if (sim_single_flag) {
|
605
|
+
/* Yes, simply update signals and advance time. */
|
606
|
+
behavior->active_time += delay;
|
607
|
+
hruby_sim_update_signals();
|
608
|
+
hruby_sim_advance_time();
|
609
|
+
} else {
|
610
|
+
/* No, handle the multi-threading. */
|
611
|
+
/* Maybe the thread is to end immediatly. */
|
612
|
+
if (sim_end_flag)
|
613
|
+
pthread_exit(NULL);
|
614
|
+
/* No go on with the wait procedure. */
|
539
615
|
pthread_mutex_lock(&hruby_sim_mutex);
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
616
|
+
/* Indicate the behavior finished current execution. */
|
617
|
+
num_active_behaviors -= 1;
|
618
|
+
// printf("!!num_active_behaviors=%d\n",num_active_behaviors);
|
619
|
+
// pthread_cond_signal(&hruby_sim_cond);
|
620
|
+
/* Update the behavior's time. */
|
621
|
+
behavior->active_time += delay;
|
546
622
|
pthread_mutex_unlock(&hruby_sim_mutex);
|
623
|
+
pthread_cond_signal(&hruby_sim_cond);
|
624
|
+
/* Wait for being reactivated. */
|
625
|
+
while(behavior->active_time > hruby_sim_time) {
|
626
|
+
pthread_mutex_lock(&hruby_sim_mutex);
|
627
|
+
while(!behaviors_can_run) {
|
628
|
+
// printf("!1\n");
|
629
|
+
// pthread_cond_wait(&compute_cond, &hruby_sim_mutex);
|
630
|
+
pthread_cond_wait(&hruby_beh_cond, &hruby_sim_mutex);
|
631
|
+
// printf("!2\n");
|
632
|
+
}
|
633
|
+
pthread_mutex_unlock(&hruby_sim_mutex);
|
634
|
+
}
|
547
635
|
}
|
548
636
|
}
|
549
637
|
|
@@ -563,6 +651,7 @@ void touch_signal(SignalI signal) {
|
|
563
651
|
* @param value the value to transmit
|
564
652
|
* @param signal the signal to transmit the value to. */
|
565
653
|
void transmit_to_signal(Value value, SignalI signal) {
|
654
|
+
// printf("Tansmit to signal: %s(%p)\n",signal->name,signal);
|
566
655
|
/* Copy the content. */
|
567
656
|
if (signal->fading)
|
568
657
|
signal->f_value = copy_value(value,signal->f_value);
|
@@ -684,7 +773,6 @@ unsigned long long make_delay(int value, Unit unit) {
|
|
684
773
|
|
685
774
|
|
686
775
|
|
687
|
-
|
688
776
|
/** Iterates over all the signals.
|
689
777
|
* @param func function to applie on each signal. */
|
690
778
|
void each_all_signal(void (*func)(SignalI)) {
|
@@ -0,0 +1,65 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <string.h>
|
3
|
+
#include <time.h>
|
4
|
+
#include <stdarg.h>
|
5
|
+
#include "hruby_sim.h"
|
6
|
+
|
7
|
+
|
8
|
+
/**
|
9
|
+
* The HDLRuby simulation mute output engine, to be used with C code
|
10
|
+
* generated by the csim engine or by the rcsim engine.
|
11
|
+
**/
|
12
|
+
|
13
|
+
/* Global variables storing the configuration of the vcd generation. */
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
/* Low-end print functions. */
|
18
|
+
|
19
|
+
/** Prints the time.
|
20
|
+
* @param time the time to show (given in ps). */
|
21
|
+
static void mute_print_time(unsigned long long time) {
|
22
|
+
}
|
23
|
+
|
24
|
+
/** Prints the name of an object without its hierarchy.
|
25
|
+
* @param object the object to print the name. */
|
26
|
+
static void mute_print_name(Object object) {
|
27
|
+
}
|
28
|
+
|
29
|
+
/** Prints the full name of an object without its hierarchy.
|
30
|
+
* @param object the object to print the name. */
|
31
|
+
static void mute_print_full_name(Object object) {
|
32
|
+
}
|
33
|
+
|
34
|
+
/** Prints a value.
|
35
|
+
* @param value the value to print */
|
36
|
+
static void mute_print_value(Value value) {
|
37
|
+
}
|
38
|
+
|
39
|
+
/** Prints a signal with its future value if any.
|
40
|
+
* @param signal the signal to show */
|
41
|
+
static void mute_print_signal_fvalue(SignalI signal) {
|
42
|
+
}
|
43
|
+
|
44
|
+
/** Prints a signal with its current value if any
|
45
|
+
* @param signal the signal to show */
|
46
|
+
static void mute_print_signal_cvalue(SignalI signal) {
|
47
|
+
}
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
/* The configuration and initialization of the vcd vizualizer. */
|
52
|
+
|
53
|
+
|
54
|
+
/** Sets up the mute vizualization engine.
|
55
|
+
* @param name the name of the vizualization. */
|
56
|
+
extern void init_mute_visualizer(char* name) {
|
57
|
+
/* Initialize the vizualizer printer engine. */
|
58
|
+
init_visualizer(&mute_print_time,
|
59
|
+
&mute_print_full_name,
|
60
|
+
&mute_print_value,
|
61
|
+
&mute_print_signal_fvalue,
|
62
|
+
&default_print_string,
|
63
|
+
&default_print_name,
|
64
|
+
&default_print_value);
|
65
|
+
}
|
@@ -106,6 +106,16 @@ Value binary(Value (*oper)(Value,Value,Value)) {
|
|
106
106
|
return oper(l,r,peek());
|
107
107
|
}
|
108
108
|
|
109
|
+
/** Selection calculation.
|
110
|
+
* @param num the number of choices to select within. */
|
111
|
+
Value select(unsigned int num) {
|
112
|
+
Value* vals = alloca(num*sizeof(Value));
|
113
|
+
int i;
|
114
|
+
/* Get the values to concat from the stack. */
|
115
|
+
for(i=1;i<=num;++i) vals[num-i] = pop();
|
116
|
+
return select_valueP(pop(),peek(),num,vals);
|
117
|
+
}
|
118
|
+
|
109
119
|
/** Cast calculation.
|
110
120
|
* @param typ the type to cast to.
|
111
121
|
* @return the destination.
|
@@ -46,11 +46,38 @@ Value calc_expression(Expression expr, Value res) {
|
|
46
46
|
Value right = get_value();
|
47
47
|
left = calc_expression(bexpr->left,left);
|
48
48
|
right = calc_expression(bexpr->right,right);
|
49
|
+
// printf("left=%.*s\n",left->capacity,left->data_str);
|
50
|
+
// printf("right=%.*s\n",right->capacity,right->data_str);
|
49
51
|
res = bexpr->oper(left,right,res);
|
50
52
|
free_value();
|
51
53
|
free_value();
|
52
54
|
break;
|
53
55
|
}
|
56
|
+
case SELECT:
|
57
|
+
{
|
58
|
+
Select sexpr = (Select)expr;
|
59
|
+
/* Calculate the selection expression. */
|
60
|
+
Value selV = get_value();
|
61
|
+
selV = calc_expression(sexpr->select,selV);
|
62
|
+
/* Is the selection defined? */
|
63
|
+
if (is_defined_value(selV)) {
|
64
|
+
/* Yes, can perform the selection. */
|
65
|
+
long long sel = value2integer(selV);
|
66
|
+
if (sel >= 0 && sel < sexpr->num_choices) {
|
67
|
+
/* Possible choice, proceed the computation. */
|
68
|
+
res = calc_expression(sexpr->choices[sel],res);
|
69
|
+
}
|
70
|
+
} else {
|
71
|
+
/* Cannot compute, simply undefines the destination. */
|
72
|
+
/* First ensure res has the right shape. */
|
73
|
+
res->type = sexpr->choices[0]->type;
|
74
|
+
resize_value(res,type_width(res->type));
|
75
|
+
/* Then make it undefined. */
|
76
|
+
set_undefined_bitstring(res);
|
77
|
+
}
|
78
|
+
free_value();
|
79
|
+
break;
|
80
|
+
}
|
54
81
|
case CONCAT:
|
55
82
|
{
|
56
83
|
Concat cexpr = (Concat)expr;
|
@@ -70,7 +97,9 @@ Value calc_expression(Expression expr, Value res) {
|
|
70
97
|
Cast cexpr = (Cast)expr;
|
71
98
|
Value child = get_value();
|
72
99
|
child = calc_expression(cexpr->child,child);
|
100
|
+
// printf("going to cast value of numeric=%d and width=%llu to width=%llu\n",child->numeric,type_width(child->type),type_width(cexpr->type));
|
73
101
|
res = cast_value(child,cexpr->type,res);
|
102
|
+
// printf("result is numeric=%d\n",res->numeric);
|
74
103
|
free_value();
|
75
104
|
break;
|
76
105
|
}
|
@@ -157,16 +186,15 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) {
|
|
157
186
|
case TRANSMIT:
|
158
187
|
{
|
159
188
|
Transmit trans = (Transmit)stmnt;
|
160
|
-
// printf("trans=%p trans->left=%p trans->left->kind=%d\n",trans,trans->left,trans->left->kind);
|
161
189
|
/* Compute the right value. */
|
162
|
-
// Value right = calc_expression(trans->right);
|
163
190
|
Value right = get_value();
|
164
191
|
right = calc_expression(trans->right,right);
|
192
|
+
// printf("transmit to left=%p with kind=%d and right=%p with kind=%d\n",trans->left,trans->left->kind,trans->right,trans->right->kind);fflush(stdout);
|
165
193
|
/* Depending on the left value. */
|
166
194
|
switch (trans->left->kind) {
|
167
195
|
case SIGNALI:
|
168
196
|
// printf("left->name=%s\n",((SignalI)(trans->left))->name);
|
169
|
-
fflush(stdout);
|
197
|
+
// fflush(stdout);
|
170
198
|
/* Simple transmission. */
|
171
199
|
if (mode)
|
172
200
|
transmit_to_signal_seq(right,(SignalI)(trans->left));
|
@@ -178,7 +206,6 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) {
|
|
178
206
|
/* Transmission to sub element. */
|
179
207
|
RefIndex refi = (RefIndex)(trans->left);
|
180
208
|
/* Compute the index. */
|
181
|
-
// Value indexV = calc_expression(refi->index);
|
182
209
|
Value indexV = get_value();
|
183
210
|
indexV = calc_expression(refi->index,indexV);
|
184
211
|
long long index = value2integer(indexV);
|
@@ -231,8 +258,9 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) {
|
|
231
258
|
/* For each sub reference. */
|
232
259
|
for(int i=0; i < refc->num_refs; ++i) {
|
233
260
|
/* Set up the transmit. */
|
234
|
-
subtrans.left = refc->refs[i];
|
235
|
-
long long size = type_width(subtrans.left->type);
|
261
|
+
subtrans.left = refc->refs[refc->num_refs-i-1];
|
262
|
+
unsigned long long size = type_width(subtrans.left->type);
|
263
|
+
// printf("i=%i left=%p left->type=%p &left->type=%p right->kind=%i pos=%llu size=%llu\n",i,subtrans.left,subtrans.left->type,&(subtrans.left->type),right->kind,pos,size,size);fflush(stdout);
|
236
264
|
subtrans.right = (Expression)get_value();
|
237
265
|
subtrans.right = (Expression)read_range(
|
238
266
|
right,pos,pos+size-1,
|
@@ -244,6 +272,7 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) {
|
|
244
272
|
free_value();
|
245
273
|
pos += size;
|
246
274
|
}
|
275
|
+
break;
|
247
276
|
}
|
248
277
|
default:
|
249
278
|
perror("Invalid kind for a reference.");
|
@@ -279,7 +308,6 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) {
|
|
279
308
|
{
|
280
309
|
HIf hif = (HIf)stmnt;
|
281
310
|
/* Calculation the condition. */
|
282
|
-
// Value condition = calc_expression(hif->condition);
|
283
311
|
Value condition = get_value();
|
284
312
|
condition = calc_expression(hif->condition,condition);
|
285
313
|
/* Is it true? */
|
@@ -290,7 +318,6 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) {
|
|
290
318
|
/* No, maybe an alternate condition is met. */
|
291
319
|
int met = 0;/* Tell if an alternate condition has been met.*/
|
292
320
|
for(int i=0; i<hif->num_noifs; ++i) {
|
293
|
-
// Value subcond = calc_expression(hif->noconds[i]);
|
294
321
|
Value subcond = get_value();
|
295
322
|
subcond = calc_expression(hif->noconds[i],subcond);
|
296
323
|
if (is_defined_value(subcond) && value2integer(subcond)){
|
@@ -305,7 +332,7 @@ void execute_statement(Statement stmnt, int mode, Behavior behavior) {
|
|
305
332
|
free_value();
|
306
333
|
}
|
307
334
|
/* Where there a sub condition met? */
|
308
|
-
if (!met) {
|
335
|
+
if (!met && hif->no) {
|
309
336
|
/* No, execute the no statement. */
|
310
337
|
execute_statement(hif->no,mode,behavior);
|
311
338
|
}
|
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
/**
|
9
9
|
* The HDLRuby simulation vcd format genertion engine, to be used with C code
|
10
|
-
* generated by
|
10
|
+
* generated by the csim engine or by the rcsim engine.
|
11
11
|
**/
|
12
12
|
|
13
13
|
/* Global variables storing the configuration of the vcd generation. */
|
@@ -74,20 +74,24 @@ static void vcd_print_name(Object object) {
|
|
74
74
|
case SCOPE:
|
75
75
|
case SYSTEMI:
|
76
76
|
case BLOCK:
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
77
|
+
{
|
78
|
+
/* Print the name if name. */
|
79
|
+
/* Trick: SystemT, Block, Scope and SystemI have the
|
80
|
+
* field name at the same place. */
|
81
|
+
char* namep = object->kind == SIGNALI ?
|
82
|
+
((SignalI)object)->name : ((Block)object)->name;
|
83
|
+
if (namep!=NULL &&
|
84
|
+
strlen(namep)>0) {
|
85
|
+
char name[256];
|
86
|
+
strncpy(name,namep,256);
|
87
|
+
replace_char(name,':','$');
|
88
|
+
vcd_print("%s",name);
|
89
|
+
} else {
|
90
|
+
/* No name, use the address of the object as name generator.*/
|
91
|
+
vcd_print("x$%p",(void*)object);
|
92
|
+
}
|
93
|
+
break;
|
89
94
|
}
|
90
|
-
break;
|
91
95
|
default: /* Nothing to do */
|
92
96
|
break;
|
93
97
|
}
|
@@ -98,7 +102,6 @@ static void vcd_print_name(Object object) {
|
|
98
102
|
* @param object the object to print the name. */
|
99
103
|
static void vcd_print_full_name(Object object) {
|
100
104
|
/* Recurse on the owner if any. */
|
101
|
-
// printf("owner=%p\n",object->owner);
|
102
105
|
if (object->owner != NULL) {
|
103
106
|
vcd_print_full_name(object->owner);
|
104
107
|
vcd_print("$");
|
@@ -107,12 +110,23 @@ static void vcd_print_full_name(Object object) {
|
|
107
110
|
vcd_print_name(object);
|
108
111
|
}
|
109
112
|
|
113
|
+
/** Prints the id of a signal in vcd indentifier format.
|
114
|
+
* @param signal the signal to print the id. */
|
115
|
+
static void vcd_print_signal_id(SignalI signal) {
|
116
|
+
size_t id = signal->id;
|
117
|
+
do {
|
118
|
+
vcd_print("%c",(id % (127-33)) + 33);
|
119
|
+
id = id / (127-33);
|
120
|
+
} while (id > 0);
|
121
|
+
}
|
122
|
+
|
110
123
|
/** Prints a value.
|
111
124
|
* @param value the value to print */
|
112
125
|
static void vcd_print_value(Value value) {
|
113
|
-
|
126
|
+
unsigned long long width = type_width(value->type);
|
127
|
+
if (width > 1) vcd_print("b");
|
114
128
|
if (value->numeric) {
|
115
|
-
unsigned long long width = type_width(value->type);
|
129
|
+
// unsigned long long width = type_width(value->type);
|
116
130
|
unsigned long long mask = 1ULL << (width-1);
|
117
131
|
for(; mask > 0; mask >>= 1) {
|
118
132
|
vcd_print("%d",(value->data_int & mask) != 0);
|
@@ -120,7 +134,7 @@ static void vcd_print_value(Value value) {
|
|
120
134
|
} else {
|
121
135
|
/* Display a bitstring value. */
|
122
136
|
unsigned long long i;
|
123
|
-
unsigned long long width = type_width(value->type);
|
137
|
+
// unsigned long long width = type_width(value->type);
|
124
138
|
char* data = value->data_str;
|
125
139
|
if (value->capacity == 0) {
|
126
140
|
/* The value is empty, therefore undefined. */
|
@@ -135,13 +149,15 @@ static void vcd_print_value(Value value) {
|
|
135
149
|
}
|
136
150
|
}
|
137
151
|
}
|
152
|
+
if (width > 1) vcd_print(" ");
|
138
153
|
}
|
139
154
|
|
140
155
|
/** Prints a signal declaration.
|
141
156
|
* @param signal the signal to declare */
|
142
157
|
static void vcd_print_var(SignalI signal) {
|
143
158
|
vcd_print("$var wire %d ",type_width(signal->type));
|
144
|
-
vcd_print_full_name((Object)signal);
|
159
|
+
// vcd_print_full_name((Object)signal);
|
160
|
+
vcd_print_signal_id(signal);
|
145
161
|
vcd_print(" ");
|
146
162
|
vcd_print_name((Object)signal);
|
147
163
|
vcd_print(" $end\n");
|
@@ -153,8 +169,9 @@ static void vcd_print_var(SignalI signal) {
|
|
153
169
|
static void vcd_print_signal_fvalue(SignalI signal) {
|
154
170
|
if (signal->f_value) {
|
155
171
|
vcd_print_value(signal->f_value);
|
156
|
-
vcd_print(" ");
|
157
|
-
vcd_print_full_name((Object)signal);
|
172
|
+
// vcd_print(" ");
|
173
|
+
// vcd_print_full_name((Object)signal);
|
174
|
+
vcd_print_signal_id(signal);
|
158
175
|
vcd_print("\n");
|
159
176
|
}
|
160
177
|
}
|
@@ -165,8 +182,9 @@ static void vcd_print_signal_fvalue(SignalI signal) {
|
|
165
182
|
static void vcd_print_signal_cvalue(SignalI signal) {
|
166
183
|
if (signal->c_value) {
|
167
184
|
vcd_print_value(signal->c_value);
|
168
|
-
vcd_print(" ");
|
169
|
-
vcd_print_full_name((Object)signal);
|
185
|
+
// vcd_print(" ");
|
186
|
+
// vcd_print_full_name((Object)signal);
|
187
|
+
vcd_print_signal_id(signal);
|
170
188
|
vcd_print("\n");
|
171
189
|
}
|
172
190
|
}
|