HDLRuby 2.3.7 → 2.4.9
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/README.md +1 -0
- data/lib/HDLRuby/hdr_samples/bstr_bench.rb +14 -0
- data/lib/HDLRuby/hdr_samples/neg_arith_bench.rb +49 -0
- data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +27 -0
- data/lib/HDLRuby/hdr_samples/with_multi_channels.rb +300 -0
- data/lib/HDLRuby/hdrcc.rb +10 -1
- data/lib/HDLRuby/hruby_bstr.rb +7 -2
- data/lib/HDLRuby/hruby_high.rb +8 -0
- data/lib/HDLRuby/hruby_low.rb +107 -8
- data/lib/HDLRuby/hruby_low2c.rb +31 -9
- data/lib/HDLRuby/hruby_low_mutable.rb +90 -2
- data/lib/HDLRuby/hruby_low_resolve.rb +1 -0
- data/lib/HDLRuby/hruby_low_without_connection.rb +1 -0
- data/lib/HDLRuby/sim/hruby_sim.h +82 -39
- data/lib/HDLRuby/sim/hruby_sim_calc.c +89 -5
- data/lib/HDLRuby/sim/hruby_sim_core.c +32 -6
- data/lib/HDLRuby/sim/hruby_sim_vcd.c +380 -0
- data/lib/HDLRuby/sim/hruby_sim_vizualize.c +51 -12
- data/lib/HDLRuby/std/fixpoint.rb +10 -2
- data/lib/HDLRuby/std/linear.rb +33 -13
- data/lib/HDLRuby/std/memory.rb +90 -20
- data/lib/HDLRuby/version.rb +1 -1
- metadata +6 -2
@@ -0,0 +1,380 @@
|
|
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 vcd format genertion engine, to be used with C code
|
10
|
+
* generated by hruby_low2c.
|
11
|
+
**/
|
12
|
+
|
13
|
+
/* Global variables storing the configuration of the vcd generation. */
|
14
|
+
|
15
|
+
/* The target file. */
|
16
|
+
static FILE* vcd_file;
|
17
|
+
|
18
|
+
/* The time scale unit in the ps. */
|
19
|
+
static unsigned long long vcd_timeunit = 1;
|
20
|
+
|
21
|
+
/* Accessing target file. */
|
22
|
+
|
23
|
+
/** Prints to the vcd file.
|
24
|
+
* @param fmt the format for handling the variadic arguments. */
|
25
|
+
static int vcd_print(char* fmt, ...) {
|
26
|
+
int ret;
|
27
|
+
|
28
|
+
/* Declare a va_list type variable */
|
29
|
+
va_list myargs;
|
30
|
+
|
31
|
+
/* Initialise the va_list variable with the ... after fmt */
|
32
|
+
va_start(myargs, fmt);
|
33
|
+
|
34
|
+
/* Forward the '...' to vprintf */
|
35
|
+
ret = vfprintf(vcd_file, fmt, myargs);
|
36
|
+
|
37
|
+
/* Clean up the va_list */
|
38
|
+
va_end(myargs);
|
39
|
+
|
40
|
+
return ret;
|
41
|
+
}
|
42
|
+
|
43
|
+
|
44
|
+
/* Utility functions for printing in vcd format. */
|
45
|
+
|
46
|
+
/* Replace all the occurences of a character with another.
|
47
|
+
* CREDIT: Superlokkus */
|
48
|
+
static char* replace_char(char* str, char find, char replace){
|
49
|
+
char *current_pos = strchr(str,find);
|
50
|
+
while (current_pos){
|
51
|
+
*current_pos = replace;
|
52
|
+
current_pos = strchr(current_pos+1,find);
|
53
|
+
}
|
54
|
+
return str;
|
55
|
+
}
|
56
|
+
|
57
|
+
|
58
|
+
/* Low-end print functions. */
|
59
|
+
|
60
|
+
/** Prints the time.
|
61
|
+
* @param time the time to show (given in ps). */
|
62
|
+
static void vcd_print_time(unsigned long long time) {
|
63
|
+
vcd_print("#%llu\n",time/vcd_timeunit);
|
64
|
+
}
|
65
|
+
|
66
|
+
|
67
|
+
/** Prints the name of an object without its hierarchy.
|
68
|
+
* @param object the object to print the name. */
|
69
|
+
static void vcd_print_name(Object object) {
|
70
|
+
/* Depending on the kind of object. */
|
71
|
+
switch(object->kind) {
|
72
|
+
case SYSTEMT:
|
73
|
+
case SIGNALI:
|
74
|
+
case SCOPE:
|
75
|
+
case SYSTEMI:
|
76
|
+
case BLOCK:
|
77
|
+
/* Print the name if name. */
|
78
|
+
/* Trick: SystemT, SignalI, Scope and SystemI have the
|
79
|
+
* field name at the same place. */
|
80
|
+
if ((((Block)object)->name != NULL) &&
|
81
|
+
strlen(((Block)object)->name)>0) {
|
82
|
+
char name[256];
|
83
|
+
strncpy(name,((Block)object)->name,256);
|
84
|
+
replace_char(name,':','$');
|
85
|
+
vcd_print("%s",name);
|
86
|
+
} else {
|
87
|
+
/* No name, use the address of the object as name generator.*/
|
88
|
+
vcd_print("$%p",(void*)object);
|
89
|
+
}
|
90
|
+
break;
|
91
|
+
default: /* Nothing to do */
|
92
|
+
break;
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
|
97
|
+
/** Prints the name of an object incluing its heirarchy.
|
98
|
+
* @param object the object to print the name. */
|
99
|
+
static void vcd_print_full_name(Object object) {
|
100
|
+
/* Recurse on the owner if any. */
|
101
|
+
// printf("owner=%p\n",object->owner);
|
102
|
+
if (object->owner != NULL) {
|
103
|
+
vcd_print_full_name(object->owner);
|
104
|
+
vcd_print("$");
|
105
|
+
}
|
106
|
+
/* Print the name of the object. */
|
107
|
+
vcd_print_name(object);
|
108
|
+
}
|
109
|
+
|
110
|
+
/** Prints a value.
|
111
|
+
* @param value the value to print */
|
112
|
+
static void vcd_print_value(Value value) {
|
113
|
+
vcd_print("b");
|
114
|
+
if (value->numeric) {
|
115
|
+
unsigned long long width = type_width(value->type);
|
116
|
+
unsigned long long mask = 1ULL << (width-1);
|
117
|
+
for(; mask > 0; mask >>= 1) {
|
118
|
+
vcd_print("%d",(value->data_int & mask) != 0);
|
119
|
+
}
|
120
|
+
} else {
|
121
|
+
/* Display a bitstring value. */
|
122
|
+
int i;
|
123
|
+
int width = type_width(value->type);
|
124
|
+
char* data = value->data_str;
|
125
|
+
if (value->capacity == 0) {
|
126
|
+
/* The value is empty, therefore undefined. */
|
127
|
+
for(i=width; i>0; --i) {
|
128
|
+
vcd_print("u");
|
129
|
+
}
|
130
|
+
}
|
131
|
+
else {
|
132
|
+
/* The value is not empty. */
|
133
|
+
for(i=width; i>0; --i) {
|
134
|
+
vcd_print("%c",data[i-1]);
|
135
|
+
}
|
136
|
+
}
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
/** Prints a signal declaration.
|
141
|
+
* @param signal the signal to declare */
|
142
|
+
static void vcd_print_var(SignalI signal) {
|
143
|
+
vcd_print("$var wire %d ",type_width(signal->type));
|
144
|
+
vcd_print_full_name((Object)signal);
|
145
|
+
vcd_print(" ");
|
146
|
+
vcd_print_name((Object)signal);
|
147
|
+
vcd_print(" $end\n");
|
148
|
+
}
|
149
|
+
|
150
|
+
|
151
|
+
/** Prints a signal with its future value if any.
|
152
|
+
* @param signal the signal to show */
|
153
|
+
static void vcd_print_signal_fvalue(SignalI signal) {
|
154
|
+
if (signal->f_value) {
|
155
|
+
vcd_print_value(signal->f_value);
|
156
|
+
vcd_print(" ");
|
157
|
+
vcd_print_full_name((Object)signal);
|
158
|
+
vcd_print("\n");
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
|
163
|
+
/** Prints a signal with its current value if any
|
164
|
+
* @param signal the signal to show */
|
165
|
+
static void vcd_print_signal_cvalue(SignalI signal) {
|
166
|
+
if (signal->c_value) {
|
167
|
+
vcd_print_value(signal->c_value);
|
168
|
+
vcd_print(" ");
|
169
|
+
vcd_print_full_name((Object)signal);
|
170
|
+
vcd_print("\n");
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
|
175
|
+
/** Prints the hierarchy content of a system type.
|
176
|
+
* @param system the system to print. */
|
177
|
+
static void vcd_print_systemT_content(SystemT system);
|
178
|
+
|
179
|
+
/** Prints the hierarchy of a scope.
|
180
|
+
* @param scope the scope to print. */
|
181
|
+
static void vcd_print_scope(Scope scope);
|
182
|
+
|
183
|
+
|
184
|
+
/** Prints the hierarchy of a block.
|
185
|
+
* @param block the block to print. */
|
186
|
+
static void vcd_print_block(Block block) {
|
187
|
+
int i;
|
188
|
+
/* Do not print block with no declaration. */
|
189
|
+
if (block->num_inners == 0) return;
|
190
|
+
|
191
|
+
/* Declares the block if named. */
|
192
|
+
vcd_print("$scope module ");
|
193
|
+
vcd_print_name((Object)block);
|
194
|
+
vcd_print(" $end\n");
|
195
|
+
|
196
|
+
/* Declare the inners of the systems. */
|
197
|
+
for(i=0; i<block->num_inners; ++i) {
|
198
|
+
vcd_print_var(block->inners[i]);
|
199
|
+
}
|
200
|
+
|
201
|
+
/* Close the hierarchy. */
|
202
|
+
vcd_print("$upscope $end\n");
|
203
|
+
}
|
204
|
+
|
205
|
+
|
206
|
+
/** Prints the hierarchy of a system instances.
|
207
|
+
* @param scope the scope to print. */
|
208
|
+
static void vcd_print_systemI(SystemI systemI) {
|
209
|
+
/* Declares the systemI. */
|
210
|
+
vcd_print("$scope module ");
|
211
|
+
vcd_print_name((Object)systemI);
|
212
|
+
vcd_print(" $end\n");
|
213
|
+
|
214
|
+
/* Declares its content. */
|
215
|
+
vcd_print_systemT_content(systemI->system);
|
216
|
+
|
217
|
+
/* Close the hierarchy. */
|
218
|
+
vcd_print("$upscope $end\n");
|
219
|
+
}
|
220
|
+
|
221
|
+
|
222
|
+
/** Prints the hierarchy inside a scope.
|
223
|
+
* @param scope the scope to print the inside. */
|
224
|
+
static void vcd_print_scope_content(Scope scope) {
|
225
|
+
int i;
|
226
|
+
|
227
|
+
/* Declare the inners of the systems. */
|
228
|
+
for(i=0; i<scope->num_inners; ++i) {
|
229
|
+
vcd_print_var(scope->inners[i]);
|
230
|
+
}
|
231
|
+
|
232
|
+
/* Recurse on the system instances. */
|
233
|
+
for(i=0; i<scope->num_systemIs; ++i) {
|
234
|
+
vcd_print_systemI(scope->systemIs[i]);
|
235
|
+
}
|
236
|
+
|
237
|
+
/* Recurse on the sub scopes. */
|
238
|
+
for(i=0; i<scope->num_scopes; ++i) {
|
239
|
+
vcd_print_scope(scope->scopes[i]);
|
240
|
+
}
|
241
|
+
|
242
|
+
/* Recurse on the behaviors. */
|
243
|
+
for(i=0; i<scope->num_behaviors; ++i) {
|
244
|
+
vcd_print_block(scope->behaviors[i]->block);
|
245
|
+
}
|
246
|
+
}
|
247
|
+
|
248
|
+
|
249
|
+
/** Prints the hierarchy of a scope.
|
250
|
+
* @param scope the scope to print. */
|
251
|
+
static void vcd_print_scope(Scope scope) {
|
252
|
+
/* Do not print block with no declaration. */
|
253
|
+
if (scope->num_inners == 0 && scope->num_scopes == 0 && scope->num_behaviors == 0) return;
|
254
|
+
/* Declares the scope. */
|
255
|
+
vcd_print("$scope module ");
|
256
|
+
vcd_print_name((Object)scope);
|
257
|
+
vcd_print(" $end\n");
|
258
|
+
|
259
|
+
/* Declares its content. */
|
260
|
+
vcd_print_scope_content(scope);
|
261
|
+
|
262
|
+
/* Close the hierarchy. */
|
263
|
+
vcd_print("$upscope $end\n");
|
264
|
+
}
|
265
|
+
|
266
|
+
|
267
|
+
/** Prints the hierarchy content of a system type.
|
268
|
+
* @param system the system to print. */
|
269
|
+
static void vcd_print_systemT_content(SystemT system) {
|
270
|
+
int i;
|
271
|
+
|
272
|
+
/* Declare the inputs of the systems. */
|
273
|
+
for(i = 0; i<system->num_inputs; ++i) {
|
274
|
+
vcd_print_var(system->inputs[i]);
|
275
|
+
}
|
276
|
+
/* Declare the outputs of the systems. */
|
277
|
+
for(i = 0; i<system->num_outputs; ++i) {
|
278
|
+
vcd_print_var(system->outputs[i]);
|
279
|
+
}
|
280
|
+
/* Declare the inouts of the systems. */
|
281
|
+
for(i = 0; i<system->num_inouts; ++i) {
|
282
|
+
vcd_print_var(system->inouts[i]);
|
283
|
+
}
|
284
|
+
/* Recurse on the content of the scope (the scope header is the system).*/
|
285
|
+
vcd_print_scope_content(system->scope);
|
286
|
+
}
|
287
|
+
|
288
|
+
|
289
|
+
/** Prints the hierarchy of a system type.
|
290
|
+
* @param system the system to print. */
|
291
|
+
static void vcd_print_systemT(SystemT system) {
|
292
|
+
int i;
|
293
|
+
/* Declares the module. */
|
294
|
+
vcd_print("$scope module ");
|
295
|
+
vcd_print_name((Object)system);
|
296
|
+
vcd_print(" $end\n");
|
297
|
+
|
298
|
+
/* Declares the content. */
|
299
|
+
vcd_print_systemT_content(system);
|
300
|
+
|
301
|
+
/* Close the hierarchy. */
|
302
|
+
vcd_print("$upscope $end\n");
|
303
|
+
}
|
304
|
+
|
305
|
+
|
306
|
+
|
307
|
+
|
308
|
+
|
309
|
+
/* high-end print functions. */
|
310
|
+
|
311
|
+
/** Prints the header of the vcd file. */
|
312
|
+
static void vcd_print_header() {
|
313
|
+
/* The date section. */
|
314
|
+
vcd_print("$date\n");
|
315
|
+
{
|
316
|
+
char text[100];
|
317
|
+
time_t now = time(NULL);
|
318
|
+
struct tm *t = localtime(&now);
|
319
|
+
strftime(text, sizeof(text), "%d %m %Y %H:%M", t);
|
320
|
+
vcd_print(" %s\n", text);
|
321
|
+
}
|
322
|
+
vcd_print("$end\n");
|
323
|
+
|
324
|
+
/* The version section. */
|
325
|
+
vcd_print("$version\n");
|
326
|
+
vcd_print(" Generated from HDLRuby simulator\n");
|
327
|
+
vcd_print("$end\n");
|
328
|
+
|
329
|
+
/* The comment section. */
|
330
|
+
vcd_print("$comment\n");
|
331
|
+
vcd_print(" Is it an easter egg?\n");
|
332
|
+
vcd_print("$end\n");
|
333
|
+
|
334
|
+
/* The time scale section: for now 1ps only. */
|
335
|
+
vcd_print("$timescale 1ps $end\n");
|
336
|
+
|
337
|
+
// /* The scope section: nothing specific. */
|
338
|
+
// vcd_print("$scope module logic $end\n");
|
339
|
+
|
340
|
+
// /* The variables declaration. */
|
341
|
+
// each_all_signal(&vcd_print_var);
|
342
|
+
|
343
|
+
// /* Ends the declarations. */
|
344
|
+
// vcd_print("$upscope $end\n");
|
345
|
+
// vcd_print("$enddefinitions $end\n");
|
346
|
+
|
347
|
+
/* The declaration of the hierarchy and the variables
|
348
|
+
* from the top system. */
|
349
|
+
vcd_print_systemT(top_system);
|
350
|
+
/* Ends the declarations. */
|
351
|
+
vcd_print("$enddefinitions $end\n");
|
352
|
+
|
353
|
+
/* Display the initializations. */
|
354
|
+
vcd_print("$dumpvars\n");
|
355
|
+
each_all_signal(&vcd_print_signal_cvalue);
|
356
|
+
vcd_print("$end\n");
|
357
|
+
}
|
358
|
+
|
359
|
+
|
360
|
+
/* The configuration and initialization of the vcd vizualizer. */
|
361
|
+
|
362
|
+
|
363
|
+
/** Sets up the vcd vizualization engine.
|
364
|
+
* @param name the name of the vizualization. */
|
365
|
+
extern void init_vcd_visualizer(char* name) {
|
366
|
+
/* Open the resulting file with name: <name>.vcd */
|
367
|
+
char filename[256];
|
368
|
+
strncpy(filename,name,256);
|
369
|
+
strncat(filename,".vcd",256);
|
370
|
+
vcd_file = fopen(filename,"w");
|
371
|
+
|
372
|
+
/* Initialize the vizualizer printer engine. */
|
373
|
+
init_visualizer(&vcd_print_time,
|
374
|
+
&vcd_print_full_name,
|
375
|
+
&vcd_print_value,
|
376
|
+
&vcd_print_signal_fvalue);
|
377
|
+
|
378
|
+
/* Prints the header of the vcd file. */
|
379
|
+
vcd_print_header();
|
380
|
+
}
|
@@ -7,26 +7,51 @@
|
|
7
7
|
* generated by hruby_low2c.
|
8
8
|
**/
|
9
9
|
|
10
|
+
/* The print function pointers. */
|
11
|
+
|
12
|
+
PrinterS printer;
|
13
|
+
|
14
|
+
|
15
|
+
/** Initializes the visualization printer engine.
|
16
|
+
* @param print_time the time printer
|
17
|
+
* @param print_name the name printer
|
18
|
+
* @param print_value the value printer
|
19
|
+
* @param print_signal the signal state printer. */
|
20
|
+
void init_visualizer(void (*print_time)(unsigned long long),
|
21
|
+
void (*print_name)(Object),
|
22
|
+
void (*print_value)(Value),
|
23
|
+
void (*print_signal)(SignalI)) {
|
24
|
+
printer.print_time = print_time;
|
25
|
+
printer.print_name = print_name;
|
26
|
+
printer.print_value = print_value;
|
27
|
+
printer.print_signal = print_signal;
|
28
|
+
}
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
/* The default printing functions. */
|
34
|
+
|
10
35
|
/** Prints the time.
|
11
36
|
* @param time the time to show. */
|
12
|
-
void
|
37
|
+
static void default_print_time(unsigned long long time) {
|
13
38
|
printf("# %llups",time);
|
14
39
|
}
|
15
40
|
|
16
41
|
/** Prints the time and goes to the next line.
|
17
|
-
* @
|
18
|
-
void
|
19
|
-
|
42
|
+
* @par1am time the time to show. */
|
43
|
+
static void default_println_time(unsigned long long time) {
|
44
|
+
default_print_time(time);
|
20
45
|
printf("\n");
|
21
46
|
}
|
22
47
|
|
23
48
|
/** Prints the name of an object.
|
24
49
|
* @param object the object to print the name. */
|
25
|
-
void
|
50
|
+
static void default_print_name(Object object) {
|
26
51
|
/* Recurse on the owner if any. */
|
27
52
|
// printf("owner=%p\n",object->owner);
|
28
53
|
if (object->owner != NULL) {
|
29
|
-
|
54
|
+
default_print_name(object->owner);
|
30
55
|
printf("::");
|
31
56
|
}
|
32
57
|
/* Depending on the kind of object. */
|
@@ -48,7 +73,7 @@ void print_name(Object object) {
|
|
48
73
|
|
49
74
|
/** Prints a value.
|
50
75
|
* @param value the value to print */
|
51
|
-
void
|
76
|
+
static void default_print_value(Value value) {
|
52
77
|
if (value->numeric) {
|
53
78
|
unsigned long long width = type_width(value->type);
|
54
79
|
unsigned long long mask = 1ULL << (width-1);
|
@@ -77,15 +102,29 @@ void print_value(Value value) {
|
|
77
102
|
|
78
103
|
/** Prints a signal.
|
79
104
|
* @param signal the signal to show */
|
80
|
-
void
|
81
|
-
|
105
|
+
static void default_print_signal(SignalI signal) {
|
106
|
+
default_print_name((Object)signal);
|
82
107
|
printf(": ");
|
83
|
-
|
108
|
+
default_print_value(signal->f_value);
|
84
109
|
}
|
85
110
|
|
86
111
|
/** Prints a signal and goes to the next line.
|
87
112
|
* @param signal the signal to show */
|
88
|
-
void
|
89
|
-
|
113
|
+
static void default_println_signal(SignalI signal) {
|
114
|
+
default_print_signal(signal);
|
90
115
|
printf("\n");
|
91
116
|
}
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
/* Set up the visualizer. */
|
121
|
+
|
122
|
+
/** Set up the default vizualization engine.
|
123
|
+
* @param name the name of the vizualization. */
|
124
|
+
void init_default_visualizer(char* name) {
|
125
|
+
/* Initialize the vizualizer printer engine. */
|
126
|
+
init_visualizer(&default_println_time,
|
127
|
+
&default_print_name,
|
128
|
+
&default_print_value,
|
129
|
+
&default_println_signal);
|
130
|
+
}
|