HDLRuby 2.11.5 → 2.11.8
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 +84 -48
- data/ext/hruby_sim/hruby_sim.h +65 -1
- data/ext/hruby_sim/hruby_sim_calc.c +211 -28
- data/ext/hruby_sim/hruby_sim_core.c +58 -4
- 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 +18 -14
- 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 +180 -69
- data/lib/HDLRuby/hruby_low_without_connection.rb +6 -2
- data/lib/HDLRuby/hruby_rcsim.rb +25 -15
- data/lib/HDLRuby/hruby_rsim.rb +63 -13
- data/lib/HDLRuby/hruby_rsim_mute.rb +35 -0
- data/lib/HDLRuby/hruby_rsim_vcd.rb +3 -3
- 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. */
|
@@ -88,12 +97,33 @@ void register_timed_behavior(Behavior behavior) {
|
|
88
97
|
}
|
89
98
|
|
90
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
|
+
|
91
121
|
/** Adds a signal for global processing.
|
92
122
|
* @param signal the signal to register */
|
93
123
|
void register_signal(SignalI signal) {
|
94
124
|
if (num_all_signals == cap_all_signals) {
|
95
125
|
if (cap_all_signals == 0) {
|
96
|
-
/* Need to create the array containing the
|
126
|
+
/* Need to create the array containing the signals. */
|
97
127
|
cap_all_signals = 100;
|
98
128
|
all_signals = calloc(cap_all_signals,sizeof(SignalI));
|
99
129
|
} else {
|
@@ -110,6 +140,24 @@ void register_signal(SignalI signal) {
|
|
110
140
|
}
|
111
141
|
|
112
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
|
+
|
113
161
|
/** Recursively update the signals until no (untimed) behavior are
|
114
162
|
* activated. */
|
115
163
|
void hruby_sim_update_signals() {
|
@@ -304,6 +352,8 @@ void hruby_sim_advance_time() {
|
|
304
352
|
if (timed_behaviors[i]->timed == 1)
|
305
353
|
if (beh_time < next_time) next_time = beh_time;
|
306
354
|
}
|
355
|
+
/* Mark again all the signals as fading. */
|
356
|
+
for(i=0; i<num_all_signals; ++i) all_signals[i]->fading = 1;
|
307
357
|
// printf("hruby_sim_time=%llu next_time=%llu\n",hruby_sim_time,next_time);
|
308
358
|
/* Sets the new activation time. */
|
309
359
|
hruby_sim_time = next_time;
|
@@ -425,7 +475,6 @@ void* behavior_run(void* arg) {
|
|
425
475
|
|
426
476
|
/** Starts a signle timed behavior to run without the multi-threaded engine. */
|
427
477
|
void hruby_sim_start_single_timed_behavior() {
|
428
|
-
int i;
|
429
478
|
// printf("hruby_sim_start_single_timed_behaviors\n");fflush(stdout);
|
430
479
|
/* Set in mono-thread mode. */
|
431
480
|
sim_single_flag = 1;
|
@@ -492,11 +541,16 @@ void hruby_sim_core(char* name, void (*init_vizualizer)(char*),
|
|
492
541
|
if (num_timed_behaviors == 1) {
|
493
542
|
/* Initialize and touch all the signals. */
|
494
543
|
hruby_sim_update_signals();
|
495
|
-
each_all_signal(&touch_signal);
|
544
|
+
// each_all_signal(&touch_signal);
|
545
|
+
run_init_behaviors();
|
496
546
|
/* Only one timed behavior, no need of the multi-threaded engine. */
|
497
547
|
hruby_sim_start_single_timed_behavior();
|
498
548
|
} else {
|
499
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();
|
500
554
|
/* Start all the timed behaviors. */
|
501
555
|
hruby_sim_start_timed_behaviors();
|
502
556
|
// /* Activate the timed behavior that are on time. */
|
@@ -597,6 +651,7 @@ void touch_signal(SignalI signal) {
|
|
597
651
|
* @param value the value to transmit
|
598
652
|
* @param signal the signal to transmit the value to. */
|
599
653
|
void transmit_to_signal(Value value, SignalI signal) {
|
654
|
+
// printf("Tansmit to signal: %s(%p)\n",signal->name,signal);
|
600
655
|
/* Copy the content. */
|
601
656
|
if (signal->fading)
|
602
657
|
signal->f_value = copy_value(value,signal->f_value);
|
@@ -718,7 +773,6 @@ unsigned long long make_delay(int value, Unit unit) {
|
|
718
773
|
|
719
774
|
|
720
775
|
|
721
|
-
|
722
776
|
/** Iterates over all the signals.
|
723
777
|
* @param func function to applie on each signal. */
|
724
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 hselect(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
|
}
|
@@ -0,0 +1,92 @@
|
|
1
|
+
|
2
|
+
# A benchmark for the arithmetic operations.
|
3
|
+
system :arith_bench do
|
4
|
+
signed[8].inner :x8,:y8,:z8,:s8
|
5
|
+
signed[10].inner :s10
|
6
|
+
signed[16].inner :x16,:y16,:z16,:s16
|
7
|
+
signed[18].inner :s18
|
8
|
+
signed[32].inner :x32,:y32,:z32,:s32
|
9
|
+
signed[34].inner :s34
|
10
|
+
|
11
|
+
s8 <= x8+y8+z8
|
12
|
+
s10 <= x8.as(signed[10])+y8+z8
|
13
|
+
|
14
|
+
s16 <= x16+y16+z16
|
15
|
+
s18 <= x16.as(signed[18])+y16+z16
|
16
|
+
|
17
|
+
s32 <= x32+y32+z32
|
18
|
+
s34 <= x32.as(signed[34])+y32+z32
|
19
|
+
|
20
|
+
timed do
|
21
|
+
x8 <= 0
|
22
|
+
y8 <= 0
|
23
|
+
z8 <= 0
|
24
|
+
x16 <= 0
|
25
|
+
y16 <= 0
|
26
|
+
z16 <= 0
|
27
|
+
x32 <= 0
|
28
|
+
y32 <= 0
|
29
|
+
z32 <= 0
|
30
|
+
!10.ns
|
31
|
+
x8 <= 1
|
32
|
+
y8 <= 1
|
33
|
+
z8 <= 1
|
34
|
+
x16 <= 1
|
35
|
+
y16 <= 1
|
36
|
+
z16 <= 1
|
37
|
+
x32 <= 1
|
38
|
+
y32 <= 1
|
39
|
+
z32 <= 1
|
40
|
+
!10.ns
|
41
|
+
x8 <= 2
|
42
|
+
y8 <= 2
|
43
|
+
z8 <= 2
|
44
|
+
x16 <= 4
|
45
|
+
y16 <= 4
|
46
|
+
z16 <= 4
|
47
|
+
x32 <= 8
|
48
|
+
y32 <= 8
|
49
|
+
z32 <= 8
|
50
|
+
!10.ns
|
51
|
+
x8 <= 0x7F
|
52
|
+
y8 <= 0x7F
|
53
|
+
z8 <= 0x7F
|
54
|
+
x16 <= 0x7FFF
|
55
|
+
y16 <= 0x7FFF
|
56
|
+
z16 <= 0x7FFF
|
57
|
+
x32 <= 0x7FFFFFFF
|
58
|
+
y32 <= 0x7FFFFFFF
|
59
|
+
z32 <= 0x7FFFFFFF
|
60
|
+
!10.ns
|
61
|
+
x8 <= -1
|
62
|
+
y8 <= -1
|
63
|
+
z8 <= -1
|
64
|
+
x16 <= -1
|
65
|
+
y16 <= -1
|
66
|
+
z16 <= -1
|
67
|
+
x32 <= -1
|
68
|
+
y32 <= -1
|
69
|
+
z32 <= -1
|
70
|
+
!10.ns
|
71
|
+
x8 <= -2
|
72
|
+
y8 <= -2
|
73
|
+
z8 <= -2
|
74
|
+
x16 <= -4
|
75
|
+
y16 <= -4
|
76
|
+
z16 <= -4
|
77
|
+
x32 <= -8
|
78
|
+
y32 <= -8
|
79
|
+
z32 <= -8
|
80
|
+
!10.ns
|
81
|
+
x8 <= -0x80
|
82
|
+
y8 <= -0x80
|
83
|
+
z8 <= -0x80
|
84
|
+
x16 <= -0x8000
|
85
|
+
y16 <= -0x8000
|
86
|
+
z16 <= -0x8000
|
87
|
+
x32 <= -0x80000000
|
88
|
+
y32 <= -0x80000000
|
89
|
+
z32 <= -0x80000000
|
90
|
+
!10.ns
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# A simple counter
|
2
|
+
system :counter do
|
3
|
+
input :clk, :rst
|
4
|
+
[8].input :inc
|
5
|
+
[8].output :count
|
6
|
+
|
7
|
+
par(clk.posedge) do
|
8
|
+
hif(rst) { count <= 0 }
|
9
|
+
helse { count <= count + inc }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# A benchmark for the counter using a constant as the inc input.
|
14
|
+
system :dff_bench do
|
15
|
+
inner :clk, :rst
|
16
|
+
[8].inner :count
|
17
|
+
[8].constant inc: 5
|
18
|
+
|
19
|
+
# counter(:my_counter).(clk,rst,inc,count)
|
20
|
+
counter(:my_counter).(clk,rst,5,count)
|
21
|
+
|
22
|
+
# par do
|
23
|
+
# my_counter.inc <= 5
|
24
|
+
# count <= my_counter.count
|
25
|
+
# end
|
26
|
+
|
27
|
+
timed do
|
28
|
+
clk <= 0
|
29
|
+
rst <= 0
|
30
|
+
!10.ns
|
31
|
+
clk <= 1
|
32
|
+
rst <= 0
|
33
|
+
!10.ns
|
34
|
+
clk <= 0
|
35
|
+
rst <= 1
|
36
|
+
!10.ns
|
37
|
+
clk <= 1
|
38
|
+
rst <= 1
|
39
|
+
!10.ns
|
40
|
+
clk <= 0
|
41
|
+
rst <= 0
|
42
|
+
!10.ns
|
43
|
+
clk <= 1
|
44
|
+
!10.ns
|
45
|
+
clk <= 0
|
46
|
+
!10.ns
|
47
|
+
clk <= 1
|
48
|
+
!10.ns
|
49
|
+
clk <= 0
|
50
|
+
!10.ns
|
51
|
+
clk <= 1
|
52
|
+
!10.ns
|
53
|
+
clk <= 0
|
54
|
+
!10.ns
|
55
|
+
clk <= 1
|
56
|
+
!10.ns
|
57
|
+
end
|
58
|
+
end
|
data/lib/HDLRuby/hdrcc.rb
CHANGED
@@ -380,6 +380,9 @@ $optparse = OptionParser.new do |opts|
|
|
380
380
|
$options[:rcsim] = v
|
381
381
|
$options[:multiple] = v
|
382
382
|
end
|
383
|
+
opts.on("--mute", "The simulator will not generate any output") do |v|
|
384
|
+
$options[:mute] = v
|
385
|
+
end
|
383
386
|
opts.on("--vcd", "The simulator will generate a vcd file") do |v|
|
384
387
|
$options[:vcd] = v
|
385
388
|
end
|
@@ -712,8 +715,9 @@ elsif $options[:clang] then
|
|
712
715
|
$main = File.open($name,"w")
|
713
716
|
|
714
717
|
# Select the vizualizer depending on the options.
|
715
|
-
init_visualizer = $options[:
|
716
|
-
|
718
|
+
init_visualizer = $options[:mute] ? "init_mute_visualizer" :
|
719
|
+
$options[:vcd] ? "init_vcd_visualizer" :
|
720
|
+
"init_default_visualizer"
|
717
721
|
|
718
722
|
# Gather the system to generate and sort them in the right order
|
719
723
|
# to ensure references are generated before being used.
|
@@ -857,9 +861,13 @@ elsif $options[:rsim] then
|
|
857
861
|
HDLRuby.show "#{Time.now}#{show_mem}"
|
858
862
|
# Ruby-level simulation.
|
859
863
|
require 'HDLRuby/hruby_rsim.rb'
|
860
|
-
# Is VCD output is required.
|
861
|
-
if $options[:
|
862
|
-
# Yes
|
864
|
+
# Is mute or VCD output is required.
|
865
|
+
if $options[:mute] then
|
866
|
+
# Yes for mute.
|
867
|
+
require "HDLRuby/hruby_rsim_mute.rb"
|
868
|
+
$top_system.sim($stdout)
|
869
|
+
elsif $options[:vcd] then
|
870
|
+
# Yes for VCD
|
863
871
|
require "HDLRuby/hruby_rsim_vcd.rb"
|
864
872
|
vcdout = File.open($output+"/hruby_simulator.vcd","w")
|
865
873
|
$top_system.sim(vcdout)
|
@@ -881,7 +889,8 @@ elsif $options[:rcsim] then
|
|
881
889
|
$top_system.to_rcsim
|
882
890
|
HDLRuby.show "Executing the hybrid C-Ruby-level simulator..."
|
883
891
|
HDLRuby.show "#{Time.now}#{show_mem}"
|
884
|
-
HDLRuby::High.rcsim($top_system,"hruby_simulator",$output
|
892
|
+
HDLRuby::High.rcsim($top_system,"hruby_simulator",$output,
|
893
|
+
($options[:mute] && 1) || ($options[:vcd] && 2) || 0)
|
885
894
|
HDLRuby.show "End of hybrid C-Ruby-level simulation..."
|
886
895
|
HDLRuby.show "#{Time.now}#{show_mem}"
|
887
896
|
elsif $options[:vhdl] then
|
data/lib/HDLRuby/hruby_bstr.rb
CHANGED
@@ -51,7 +51,9 @@ module HDLRuby
|
|
51
51
|
elsif val.is_a?(Numeric) then
|
52
52
|
# Content is a numeric.
|
53
53
|
@content = []
|
54
|
-
if val
|
54
|
+
if val == 0 then
|
55
|
+
@content << 0
|
56
|
+
elsif val > 0 then
|
55
57
|
while val > 0 do
|
56
58
|
@content << (val & 1)
|
57
59
|
val /= 2
|
@@ -110,6 +112,11 @@ module HDLRuby
|
|
110
112
|
return @content
|
111
113
|
end
|
112
114
|
|
115
|
+
# Hash comparison.
|
116
|
+
def eql?(bstr)
|
117
|
+
return @content.eql?(bstr.raw_content)
|
118
|
+
end
|
119
|
+
|
113
120
|
# Tells if the bit string is strictly.
|
114
121
|
#
|
115
122
|
# NOTE: return false if the sign is undefined of if it is unknown
|
@@ -180,10 +187,14 @@ module HDLRuby
|
|
180
187
|
if right >= left then
|
181
188
|
# puts "left=#{left} right=#{right}"
|
182
189
|
# Get the corresponding bits as a BitString
|
183
|
-
return BitString.new(@content[left..right],:raw)
|
190
|
+
# return BitString.new(@content[left..right],:raw)
|
191
|
+
# set to positive.
|
192
|
+
return BitString.new(@content[left..right]+[0],:raw)
|
184
193
|
else
|
185
194
|
# Get the corresponding bits as a BitString
|
186
|
-
return BitString.new(@content[right..left].reverse,:raw)
|
195
|
+
# return BitString.new(@content[right..left].reverse,:raw)
|
196
|
+
# set to positive.
|
197
|
+
return BitString.new(@content[right..left].reverse+[0],:raw)
|
187
198
|
end
|
188
199
|
else
|
189
200
|
# Process the index.
|
@@ -532,6 +543,7 @@ module HDLRuby
|
|
532
543
|
val = BitString.new(val)
|
533
544
|
end
|
534
545
|
vcontent = val.raw_content
|
546
|
+
# puts "vcontent=#{vcontent}"
|
535
547
|
width = vcontent.size > @content.size ? vcontent.size : @content.size
|
536
548
|
res_content = width.times.map do |i|
|
537
549
|
# Get the bits to compute with
|
data/lib/HDLRuby/hruby_high.rb
CHANGED
@@ -4213,7 +4213,7 @@ module HDLRuby::High
|
|
4213
4213
|
# Creates a new +type+ sort of block with possible +name+
|
4214
4214
|
# and build it by executing +ruby_block+.
|
4215
4215
|
def initialize(type, name = :"", &ruby_block)
|
4216
|
-
# Initialize the
|
4216
|
+
# Initialize the behavior.
|
4217
4217
|
super(type,name)
|
4218
4218
|
|
4219
4219
|
unless name.empty? then
|
@@ -4674,7 +4674,11 @@ module HDLRuby::High
|
|
4674
4674
|
class ::Integer
|
4675
4675
|
# Converts to a new high-level expression.
|
4676
4676
|
def to_expr
|
4677
|
-
|
4677
|
+
if (self.bit_length <= 63) then
|
4678
|
+
return Value.new(Integer,self)
|
4679
|
+
else
|
4680
|
+
return Value.new(TypeSigned.new(:"",self.bit_length..0),self)
|
4681
|
+
end
|
4678
4682
|
end
|
4679
4683
|
end
|
4680
4684
|
|
@@ -5168,9 +5172,9 @@ module HDLRuby::High
|
|
5168
5172
|
|
5169
5173
|
|
5170
5174
|
# Standard vector types.
|
5171
|
-
Integer = TypeSigned.new(:integer)
|
5175
|
+
Integer = TypeSigned.new(:integer,63..0)
|
5172
5176
|
Char = TypeSigned.new(:char,7..0)
|
5173
|
-
Natural = TypeUnsigned.new(:natural)
|
5177
|
+
Natural = TypeUnsigned.new(:natural,63..0)
|
5174
5178
|
Bignum = TypeSigned.new(:bignum,HDLRuby::Infinity..0)
|
5175
5179
|
Real = TypeFloat.new(:float)
|
5176
5180
|
|