HDLRuby 2.3.6 → 2.4.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 print_time(unsigned long long time) {
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
- * @param time the time to show. */
18
- void println_time(unsigned long long time) {
19
- print_time(time);
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 print_name(Object object) {
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
- print_name(object->owner);
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 print_value(Value value) {
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 print_signal(SignalI signal) {
81
- print_name((Object)signal);
105
+ static void default_print_signal(SignalI signal) {
106
+ default_print_name((Object)signal);
82
107
  printf(": ");
83
- print_value(signal->f_value);
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 println_signal(SignalI signal) {
89
- print_signal(signal);
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
+ }