HDLRuby 2.3.8 → 2.4.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,6 +12,9 @@
12
12
  * hruby_low2c.
13
13
  * */
14
14
 
15
+ /** The top system. */
16
+ SystemT top_system;
17
+
15
18
  /** The number of all the signals. */
16
19
  static int num_all_signals = 0;
17
20
  /** The capacity of the set of signals. */
@@ -118,9 +121,10 @@ void hruby_sim_update_signals() {
118
121
  /* Is there a change? */
119
122
  if (same_content_value(sig->c_value,sig->f_value)) continue;
120
123
  /* Yes, process the signal. */
121
- println_signal(sig);
122
- // printf("c_value="); print_value(sig->c_value);
123
- // printf("\nf_value="); print_value(sig->f_value); printf("\n");
124
+ // println_signal(sig);
125
+ printer.print_signal(sig);
126
+ // printf("c_value="); printer.print_value(sig->c_value);
127
+ // printf("\nf_value="); printer.print_value(sig->f_value); printf("\n");
124
128
  // printf("Touched signal: %p (%s)\n",sig,sig->name);
125
129
  /* Update the current value of the signal. */
126
130
  copy_value(sig->f_value,sig->c_value);
@@ -185,7 +189,8 @@ void hruby_sim_update_signals() {
185
189
  SignalI sig = e->data;
186
190
  delete_element(e);
187
191
  /* Yes, process the signal. */
188
- println_signal(sig);
192
+ // println_signal(sig);
193
+ printer.print_signal(sig);
189
194
  /* Update the current value of the signal. */
190
195
  /* Mark the corresponding code as activated. */
191
196
  /* Any edge activation. */
@@ -284,7 +289,8 @@ void hruby_sim_advance_time() {
284
289
  }
285
290
  /* Sets the new activation time. */
286
291
  hruby_sim_time = next_time;
287
- println_time(hruby_sim_time);
292
+ // println_time(hruby_sim_time);
293
+ printer.print_time(hruby_sim_time);
288
294
  }
289
295
 
290
296
 
@@ -393,9 +399,18 @@ void hruby_sim_end_timed_behaviors() {
393
399
 
394
400
 
395
401
 
402
+ // /** The simulation core function.
403
+ // * @param limit the time limit in fs. */
404
+ // void hruby_sim_core(unsigned long long limit) {
396
405
  /** The simulation core function.
406
+ * @param name the name of the simulation.
407
+ * @param vizualizer the vizualizer engine initializer.
397
408
  * @param limit the time limit in fs. */
398
- void hruby_sim_core(unsigned long long limit) {
409
+ void hruby_sim_core(char* name, void (*init_vizualizer)(char*),
410
+ unsigned long long limit) {
411
+ /* Initilize the vizualizer. */
412
+ init_vizualizer(name);
413
+
399
414
  /* Initialize the time to 0. */
400
415
  hruby_sim_time = 0;
401
416
 
@@ -597,3 +612,14 @@ unsigned long long make_delay(int value, Unit unit) {
597
612
  return -1;
598
613
  }
599
614
 
615
+
616
+
617
+
618
+ /* Iterate over all the signals.
619
+ * @param func function to applie on each signal. */
620
+ void each_all_signal(void (*func)(SignalI)) {
621
+ int i;
622
+ for(i = 0; i<num_all_signals; ++i) {
623
+ func(all_signals[i]);
624
+ }
625
+ }
@@ -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
+ }