HDLRuby 2.11.4 → 2.11.7
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/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
|
}
|