HDLRuby 2.10.5 → 2.11.0
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/HDLRuby.gemspec +1 -0
- data/README.md +8 -4
- data/Rakefile +8 -0
- data/{lib/HDLRuby/sim/Makefile → ext/hruby_sim/Makefile_csim} +0 -0
- data/ext/hruby_sim/extconf.rb +13 -0
- data/ext/hruby_sim/hruby_rcsim_build.c +1188 -0
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim.h +255 -16
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_calc.c +310 -181
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_core.c +34 -17
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_list.c +0 -0
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_stack_calc.c +4 -1
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_stack_calc.c.sav +0 -0
- data/ext/hruby_sim/hruby_sim_tree_calc.c +375 -0
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_vcd.c +5 -5
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_sim_vizualize.c +2 -2
- data/{lib/HDLRuby/sim → ext/hruby_sim}/hruby_value_pool.c +4 -1
- data/lib/HDLRuby/hdr_samples/bstr_bench.rb +2 -0
- data/lib/HDLRuby/hdr_samples/case_bench.rb +2 -2
- data/lib/HDLRuby/hdr_samples/counter_bench.rb +0 -1
- data/lib/HDLRuby/hdr_samples/counter_dff_bench.rb +46 -0
- data/lib/HDLRuby/hdr_samples/dff_bench.rb +1 -1
- data/lib/HDLRuby/hdr_samples/print_bench.rb +62 -0
- data/lib/HDLRuby/hdr_samples/rom.rb +5 -3
- data/lib/HDLRuby/hdr_samples/simple_counter_bench.rb +43 -0
- data/lib/HDLRuby/hdrcc.rb +54 -8
- data/lib/HDLRuby/hruby_bstr.rb +1175 -917
- data/lib/HDLRuby/hruby_high.rb +200 -90
- data/lib/HDLRuby/hruby_high_fullname.rb +82 -0
- data/lib/HDLRuby/hruby_low.rb +41 -23
- data/lib/HDLRuby/hruby_low2c.rb +7 -0
- data/lib/HDLRuby/hruby_rcsim.rb +978 -0
- data/lib/HDLRuby/hruby_rsim.rb +1134 -0
- data/lib/HDLRuby/hruby_rsim_vcd.rb +322 -0
- data/lib/HDLRuby/hruby_values.rb +362 -18
- data/lib/HDLRuby/hruby_verilog.rb +21 -3
- data/lib/HDLRuby/version.rb +1 -1
- metadata +24 -13
@@ -0,0 +1,1188 @@
|
|
1
|
+
#ifdef RCSIM
|
2
|
+
|
3
|
+
#include <stdio.h>
|
4
|
+
#include <stdarg.h>
|
5
|
+
#include <stdlib.h>
|
6
|
+
#include <string.h>
|
7
|
+
#include <limits.h>
|
8
|
+
|
9
|
+
#include <ruby.h>
|
10
|
+
#include "extconf.h"
|
11
|
+
|
12
|
+
#include "hruby_sim.h"
|
13
|
+
|
14
|
+
/**
|
15
|
+
* The C-Ruby hybrid HDLRuby simulation builder.
|
16
|
+
**/
|
17
|
+
|
18
|
+
|
19
|
+
/*#### Creating the VALUE wrapper of C simulation objects. */
|
20
|
+
|
21
|
+
// #define rcsim_wrapper(TYPE) \
|
22
|
+
// static const rb_data_type_t TYPE ## _ruby = { \
|
23
|
+
// #TYPE ,\
|
24
|
+
// {0, free_dbm, memsize_dbm,},\
|
25
|
+
// 0, 0,\
|
26
|
+
// RUBY_TYPED_FREE_IMMEDIATELY, }
|
27
|
+
//
|
28
|
+
// #define rcsim_to_value(TYPE, POINTER, VALUE) \
|
29
|
+
// (VALUE) = TypedData_Make_Struct(klass, TYPE , &( TYPE ## _ruby ), (POINTER) )
|
30
|
+
//
|
31
|
+
// #define value_to_rcsim(VALUE, TYPE, POINTER) \
|
32
|
+
// TypedData_Get_Struct((VALUE), TYPE , &( TYPE ## _ruby ), (POINTER) );
|
33
|
+
//
|
34
|
+
// rcsim_wrapper(Type);
|
35
|
+
// rcsim_wrapper(SystemT);
|
36
|
+
// rcsim_wrapper(Scope);
|
37
|
+
// rcsim_wrapper(Behavior);
|
38
|
+
// rcsim_wrapper(Event);
|
39
|
+
// rcsim_wrapper(SignalI);
|
40
|
+
// rcsim_wrapper(SystemI);
|
41
|
+
// rcsim_wrapper(Statement);
|
42
|
+
// rcsim_wrapper(Transmit);
|
43
|
+
// rcsim_wrapper(Print);
|
44
|
+
// rcsim_wrapper(TimeWait);
|
45
|
+
// rcsim_wrapper(TimeTerminate);
|
46
|
+
// rcsim_wrapper(HIf);
|
47
|
+
// rcsim_wrapper(HCase);
|
48
|
+
// rcsim_wrapper(Block);
|
49
|
+
// rcsim_wrapper(Value);
|
50
|
+
// rcsim_wrapper(Expression);
|
51
|
+
// rcsim_wrapper(Cast);
|
52
|
+
// rcsim_wrapper(Unary);
|
53
|
+
// rcsim_wrapper(Binary);
|
54
|
+
// rcsim_wrapper(Select);
|
55
|
+
// rcsim_wrapper(Concat);
|
56
|
+
// rcsim_wrapper(Reference);
|
57
|
+
// rcsim_wrapper(RefConcat);
|
58
|
+
// rcsim_wrapper(RefIndex);
|
59
|
+
// rcsim_wrapper(RefRange);
|
60
|
+
|
61
|
+
static VALUE RCSimPointer;
|
62
|
+
|
63
|
+
#define rcsim_to_value(TYPE,POINTER,VALUE) \
|
64
|
+
(VALUE) = Data_Wrap_Struct(RCSimPointer, 0, 0, (POINTER))
|
65
|
+
// (VALUE) = Data_Wrap_Struct(RCSimPointer, 0, free, (POINTER))
|
66
|
+
// (VALUE) = ULL2NUM((unsigned long long)(POINTER))
|
67
|
+
|
68
|
+
#define value_to_rcsim(TYPE,VALUE,POINTER) \
|
69
|
+
Data_Get_Struct((VALUE),TYPE,(POINTER))
|
70
|
+
// (POINTER) = (TYPE*)NUM2ULL((VALUE))
|
71
|
+
|
72
|
+
/*#### Generates the list of ID coressponding to the HDLRuby symbols. ####*/
|
73
|
+
|
74
|
+
static ID id_ANYEDGE;
|
75
|
+
static ID id_POSEDGE;
|
76
|
+
static ID id_NEGEDGE;
|
77
|
+
static ID id_PAR;
|
78
|
+
static ID id_SEQ;
|
79
|
+
// static ID id_NOT;
|
80
|
+
// static ID id_NEG;
|
81
|
+
// static ID id_ADD;
|
82
|
+
// static ID id_SUB;
|
83
|
+
// static ID id_MUL;
|
84
|
+
// static ID id_DIV;
|
85
|
+
// static ID id_MOD;
|
86
|
+
// static ID id_POW;
|
87
|
+
// static ID id_AND;
|
88
|
+
// static ID id_OR ;
|
89
|
+
// static ID id_XOR;
|
90
|
+
// static ID id_SHL;
|
91
|
+
// static ID id_SHR;
|
92
|
+
// static ID id_EQ;
|
93
|
+
// static ID id_NE;
|
94
|
+
// static ID id_LT;
|
95
|
+
// static ID id_LE;
|
96
|
+
// static ID id_GT;
|
97
|
+
// static ID id_GE;
|
98
|
+
|
99
|
+
void make_sym_IDs() {
|
100
|
+
id_ANYEDGE = rb_intern("anyedge");
|
101
|
+
id_POSEDGE = rb_intern("posedge");
|
102
|
+
id_NEGEDGE = rb_intern("negedge");
|
103
|
+
id_PAR = rb_intern("par");
|
104
|
+
id_SEQ = rb_intern("seq");
|
105
|
+
// id_NOT = rb_intern("~");
|
106
|
+
// id_NEG = rb_intern("-@");
|
107
|
+
// id_ADD = rb_intern("+");
|
108
|
+
// id_SUB = rb_intern("-");
|
109
|
+
// id_MUL = rb_intern("*");
|
110
|
+
// id_DIV = rb_intern("/");
|
111
|
+
// id_MOD = rb_intern("%");
|
112
|
+
// id_POW = rb_intern("**");
|
113
|
+
// id_AND = rb_intern("&");
|
114
|
+
// id_OR = rb_intern("|");
|
115
|
+
// id_XOR = rb_intern("^");
|
116
|
+
// id_SHL = rb_intern("<<");
|
117
|
+
// id_SHR = rb_intern(">>");
|
118
|
+
// id_EQ = rb_intern("==");
|
119
|
+
// id_NE = rb_intern("!=");
|
120
|
+
// id_LT = rb_intern("<");
|
121
|
+
// id_LE = rb_intern("<=");
|
122
|
+
// id_GT = rb_intern(">");
|
123
|
+
// id_GE = rb_intern(">=");
|
124
|
+
}
|
125
|
+
|
126
|
+
/** Converts a symbol to a char value.
|
127
|
+
* NOTE: only works for one or two ASCII characters symbols. */
|
128
|
+
static unsigned char sym_to_char(VALUE sym) {
|
129
|
+
const char* sym_ptr = rb_id2name(SYM2ID(sym));
|
130
|
+
// printf("sym_ptr=%s char=%i\n",sym_ptr,(unsigned char)(sym_ptr[0]+sym_ptr[1]*2));
|
131
|
+
return (unsigned char)(sym_ptr[0]+sym_ptr[1]*2);
|
132
|
+
}
|
133
|
+
|
134
|
+
|
135
|
+
/*#### Getting the C simulation type objects. ####*/
|
136
|
+
|
137
|
+
/* Get the bit type. */
|
138
|
+
VALUE rcsim_get_type_bit(VALUE mod) {
|
139
|
+
VALUE res;
|
140
|
+
rcsim_to_value(TypeS,get_type_bit(),res);
|
141
|
+
return res;
|
142
|
+
}
|
143
|
+
|
144
|
+
/* Get the signed type. */
|
145
|
+
VALUE rcsim_get_type_signed(VALUE mod) {
|
146
|
+
VALUE res;
|
147
|
+
rcsim_to_value(TypeS,get_type_signed(),res);
|
148
|
+
return res;
|
149
|
+
}
|
150
|
+
|
151
|
+
/* Get a vector type. */
|
152
|
+
VALUE rcsim_get_type_vector(VALUE mod, VALUE baseV, VALUE numV) {
|
153
|
+
/* Get the base type. */
|
154
|
+
Type base;
|
155
|
+
value_to_rcsim(TypeS,baseV,base);
|
156
|
+
/* Get the number of elements. */
|
157
|
+
unsigned long long num = NUM2LL(numV);
|
158
|
+
/* Get the type. */
|
159
|
+
Type type = get_type_vector(base,num);
|
160
|
+
/* Return it as a Ruby VALUE. */
|
161
|
+
VALUE res;
|
162
|
+
rcsim_to_value(TypeS,type,res);
|
163
|
+
return res;
|
164
|
+
}
|
165
|
+
|
166
|
+
|
167
|
+
/*#### Creating the C simulation objects. ####*/
|
168
|
+
|
169
|
+
/* Creating a systemT C object. */
|
170
|
+
VALUE rcsim_make_systemT(VALUE mod, VALUE name) {
|
171
|
+
/* Allocates the systemT. */
|
172
|
+
SystemT systemT = (SystemT)malloc(sizeof(SystemTS));
|
173
|
+
/* Set it up. */
|
174
|
+
systemT->kind = SYSTEMT;
|
175
|
+
systemT->owner = NULL;
|
176
|
+
systemT->name = strdup(StringValueCStr(name));
|
177
|
+
systemT->num_inputs = 0;
|
178
|
+
systemT->inputs = NULL;
|
179
|
+
systemT->num_outputs = 0;
|
180
|
+
systemT->outputs = NULL;
|
181
|
+
systemT->num_inouts = 0;
|
182
|
+
systemT->inouts = NULL;
|
183
|
+
systemT->scope = NULL;
|
184
|
+
// printf("Created systemT with kind=%d and name=%s\n",systemT->kind,systemT->name);
|
185
|
+
/* Returns the C systemT embedded into a ruby VALUE. */
|
186
|
+
VALUE res;
|
187
|
+
rcsim_to_value(SystemTS,systemT,res);
|
188
|
+
return res;
|
189
|
+
}
|
190
|
+
|
191
|
+
|
192
|
+
/* Creating a scope C object. */
|
193
|
+
VALUE rcsim_make_scope(VALUE mod, VALUE name) {
|
194
|
+
/* Allocates the scope. */
|
195
|
+
Scope scope = (Scope)malloc(sizeof(ScopeS));
|
196
|
+
/* Set it up. */
|
197
|
+
scope->kind = SCOPE;
|
198
|
+
scope->owner = NULL;
|
199
|
+
scope->name = strdup(StringValueCStr(name));
|
200
|
+
scope->num_systemIs = 0;
|
201
|
+
scope->systemIs = NULL;
|
202
|
+
scope->num_inners = 0;
|
203
|
+
scope->inners = NULL;
|
204
|
+
scope->num_scopes = 0;
|
205
|
+
scope->scopes = NULL;
|
206
|
+
scope->num_behaviors = 0;
|
207
|
+
scope->behaviors = NULL;
|
208
|
+
scope->num_codes = 0;
|
209
|
+
scope->codes = NULL;
|
210
|
+
/* Returns the C scope embedded into a ruby VALUE. */
|
211
|
+
VALUE res;
|
212
|
+
rcsim_to_value(ScopeS,scope,res);
|
213
|
+
return res;
|
214
|
+
}
|
215
|
+
|
216
|
+
|
217
|
+
/* Creating a behavior C object. */
|
218
|
+
VALUE rcsim_make_behavior(VALUE mod, VALUE timed) {
|
219
|
+
/* Allocates the behavior. */
|
220
|
+
Behavior behavior = (Behavior)malloc(sizeof(BehaviorS));
|
221
|
+
// printf("new behavior=%p\n",behavior);
|
222
|
+
/* Set it up. */
|
223
|
+
behavior->kind = BEHAVIOR;
|
224
|
+
behavior->owner = NULL;
|
225
|
+
behavior->num_events = 0;
|
226
|
+
behavior->events = NULL;
|
227
|
+
behavior->enabled = 0;
|
228
|
+
behavior->activated = 0;
|
229
|
+
if (TYPE(timed) == T_TRUE) {
|
230
|
+
/* The behavior is timed, set it up and register it. */
|
231
|
+
behavior->timed = 1;
|
232
|
+
register_timed_behavior(behavior);
|
233
|
+
} else {
|
234
|
+
/* The behavior is not timed. */
|
235
|
+
behavior->timed = 0;
|
236
|
+
}
|
237
|
+
behavior->active_time = 0;
|
238
|
+
/* Returns the C behavior embedded into a ruby VALUE. */
|
239
|
+
VALUE res;
|
240
|
+
rcsim_to_value(BehaviorS,behavior,res);
|
241
|
+
return res;
|
242
|
+
}
|
243
|
+
|
244
|
+
|
245
|
+
/* Creating an event C object. */
|
246
|
+
VALUE rcsim_make_event(VALUE mod, VALUE typeV, VALUE sigV) {
|
247
|
+
/* Allocates the event. */
|
248
|
+
Event event = (Event)malloc(sizeof(EventS));
|
249
|
+
/* Set it up. */
|
250
|
+
event->kind = EVENT;
|
251
|
+
event->owner = NULL;
|
252
|
+
/* Its type. */
|
253
|
+
ID id_edge = SYM2ID(typeV);
|
254
|
+
if (id_edge == id_POSEDGE) { event->edge = POSEDGE; }
|
255
|
+
else if (id_edge == id_NEGEDGE) { event->edge = NEGEDGE; }
|
256
|
+
else if (id_edge == id_ANYEDGE) { event->edge = ANYEDGE; }
|
257
|
+
else { perror("Invalid edge type."); }
|
258
|
+
/* Its signal. */
|
259
|
+
value_to_rcsim(SignalIS,sigV,event->signal);
|
260
|
+
/* Returns the C event embedded into a ruby VALUE. */
|
261
|
+
VALUE res;
|
262
|
+
rcsim_to_value(EventS,event,res);
|
263
|
+
return res;
|
264
|
+
}
|
265
|
+
|
266
|
+
|
267
|
+
/* Creating a signal C object. */
|
268
|
+
VALUE rcsim_make_signal(VALUE mod, VALUE name, VALUE type) {
|
269
|
+
/* Allocates the signal. */
|
270
|
+
SignalI signal = (SignalI)malloc(sizeof(SignalIS));
|
271
|
+
/* Set it up. */
|
272
|
+
signal->kind = SIGNALI;
|
273
|
+
signal->owner = NULL;
|
274
|
+
signal->name = strdup(StringValueCStr(name));
|
275
|
+
// printf("Creating signal named=%s\n",signal->name);
|
276
|
+
value_to_rcsim(TypeS,type,signal->type);
|
277
|
+
// printf("type width=%llu\n",type_width(signal->type));
|
278
|
+
signal->c_value = make_value(signal->type,0);
|
279
|
+
signal->c_value->signal = signal;
|
280
|
+
// printf("c_value=%p type=%p\n",signal->c_value,signal->c_value->type);
|
281
|
+
// printf("c_value type width=%llu\n",type_width(signal->c_value->type));
|
282
|
+
signal->f_value = make_value(signal->type,0);
|
283
|
+
signal->f_value->signal = signal;
|
284
|
+
signal->fading = 1; /* Initially the signal can be overwritten by anything.*/
|
285
|
+
signal->num_any = 0;
|
286
|
+
signal->any = NULL;
|
287
|
+
signal->num_pos = 0;
|
288
|
+
signal->pos = NULL;
|
289
|
+
signal->num_neg = 0;
|
290
|
+
signal->neg = NULL;
|
291
|
+
/* Register the signal. */
|
292
|
+
register_signal(signal);
|
293
|
+
/* Returns the C signal embedded into a ruby VALUE. */
|
294
|
+
VALUE res;
|
295
|
+
rcsim_to_value(SignalIS,signal,res);
|
296
|
+
return res;
|
297
|
+
}
|
298
|
+
|
299
|
+
|
300
|
+
/* Creating a system instance C object. */
|
301
|
+
VALUE rcsim_make_systemI(VALUE mod, VALUE name, VALUE systemT) {
|
302
|
+
/* Allocates the system instance. */
|
303
|
+
SystemI systemI = (SystemI)malloc(sizeof(SystemIS));
|
304
|
+
/* Set it up. */
|
305
|
+
systemI->kind = SYSTEMI;
|
306
|
+
systemI->owner = NULL;
|
307
|
+
systemI->name = strdup(StringValueCStr(name));
|
308
|
+
// /* Name is made empty since redundant with Eigen system. */
|
309
|
+
// systemI->name = "";
|
310
|
+
value_to_rcsim(SystemTS,systemT,systemI->system);
|
311
|
+
systemI->num_systems = 1;
|
312
|
+
systemI->systems = (SystemT*)malloc(sizeof(SystemT));
|
313
|
+
systemI->systems[0] = systemI->system;
|
314
|
+
/* Configure the systemI to execute the default systemT. */
|
315
|
+
configure(systemI,0);
|
316
|
+
/* Returns the C system instance embedded into a ruby VALUE. */
|
317
|
+
VALUE res;
|
318
|
+
rcsim_to_value(SystemIS,systemI,res);
|
319
|
+
return res;
|
320
|
+
}
|
321
|
+
|
322
|
+
|
323
|
+
/* Creating a transmit C object. */
|
324
|
+
VALUE rcsim_make_transmit(VALUE mod, VALUE left, VALUE right) {
|
325
|
+
/* Allocates the transmit. */
|
326
|
+
Transmit transmit = (Transmit)malloc(sizeof(TransmitS));
|
327
|
+
/* Set it up. */
|
328
|
+
transmit->kind = TRANSMIT;
|
329
|
+
value_to_rcsim(ReferenceS,left,transmit->left);
|
330
|
+
value_to_rcsim(ExpressionS,right,transmit->right);
|
331
|
+
/* Returns the C transmit embedded into a ruby VALUE. */
|
332
|
+
VALUE res;
|
333
|
+
rcsim_to_value(TransmitS,transmit,res);
|
334
|
+
return res;
|
335
|
+
}
|
336
|
+
|
337
|
+
|
338
|
+
/* Creating a print C object. */
|
339
|
+
VALUE rcsim_make_print(VALUE mod) {
|
340
|
+
/* Allocates the print. */
|
341
|
+
Print print = (Print)malloc(sizeof(PrintS));
|
342
|
+
/* Set it up. */
|
343
|
+
print->kind = PRINT;
|
344
|
+
print->num_args = 0;
|
345
|
+
print->args = NULL;
|
346
|
+
/* Returns the C print embedded into a ruby VALUE. */
|
347
|
+
VALUE res;
|
348
|
+
rcsim_to_value(PrintS,print,res);
|
349
|
+
return res;
|
350
|
+
}
|
351
|
+
|
352
|
+
|
353
|
+
/* Creating a time wait C object. */
|
354
|
+
VALUE rcsim_make_timeWait(VALUE mod, VALUE unitV, VALUE delayV) {
|
355
|
+
/* Allocates the time wait. */
|
356
|
+
TimeWait timeWait = (TimeWait)malloc(sizeof(TimeWaitS));
|
357
|
+
/* Set it up. */
|
358
|
+
timeWait->kind = TIME_WAIT;
|
359
|
+
/* Compute the delay. */
|
360
|
+
unsigned long long delay;
|
361
|
+
delay = NUM2LL(delayV);
|
362
|
+
/* Adjust the delay depending on the unit. */
|
363
|
+
const char* unit = rb_id2name(SYM2ID(unitV));
|
364
|
+
switch(unit[0]) {
|
365
|
+
case 'p': /* Ok as is. */ break;
|
366
|
+
case 'n': delay *= 1000; break;
|
367
|
+
case 'u': delay *= 1000000; break;
|
368
|
+
case 'm': delay *= 1000000000; break;
|
369
|
+
case 's': delay *= 1000000000000; break;
|
370
|
+
default:
|
371
|
+
perror("Invalid delay unit.");
|
372
|
+
}
|
373
|
+
timeWait->delay = delay;
|
374
|
+
/* Returns the C time wait embedded into a ruby VALUE. */
|
375
|
+
VALUE res;
|
376
|
+
rcsim_to_value(TimeWaitS,timeWait,res);
|
377
|
+
return res;
|
378
|
+
}
|
379
|
+
|
380
|
+
|
381
|
+
/* Creating a time terminate C object. */
|
382
|
+
VALUE rcsim_make_timeTerminate(VALUE mod) {
|
383
|
+
/* Allocates the time terminate. */
|
384
|
+
TimeTerminate timeTerminate = (TimeTerminate)malloc(sizeof(TimeTerminateS));
|
385
|
+
/* Set it up. */
|
386
|
+
timeTerminate->kind = TIME_TERMINATE;
|
387
|
+
/* Returns the C time terminate embedded into a ruby VALUE. */
|
388
|
+
VALUE res;
|
389
|
+
rcsim_to_value(TimeTerminateS,timeTerminate,res);
|
390
|
+
return res;
|
391
|
+
}
|
392
|
+
|
393
|
+
|
394
|
+
/* Creating a hardware if C object. */
|
395
|
+
VALUE rcsim_make_hif(VALUE mod, VALUE condition, VALUE yes, VALUE no) {
|
396
|
+
/* Allocates the hardware if. */
|
397
|
+
HIf hif = (HIf)malloc(sizeof(HIfS));
|
398
|
+
/* Set it up. */
|
399
|
+
hif->kind = HIF;
|
400
|
+
value_to_rcsim(ExpressionS,condition,hif->condition);
|
401
|
+
value_to_rcsim(StatementS,yes,hif->yes);
|
402
|
+
if (TYPE(no) == T_NIL)
|
403
|
+
hif->no = NULL;
|
404
|
+
else
|
405
|
+
value_to_rcsim(StatementS,no,hif->no);
|
406
|
+
hif->num_noifs = 0;
|
407
|
+
hif->noconds = NULL;
|
408
|
+
hif->nostmnts = NULL;
|
409
|
+
/* Returns the C hardware if embedded into a ruby VALUE. */
|
410
|
+
VALUE res;
|
411
|
+
rcsim_to_value(HIfS,hif,res);
|
412
|
+
return res;
|
413
|
+
}
|
414
|
+
|
415
|
+
|
416
|
+
/* Creating a hardware case C object. */
|
417
|
+
VALUE rcsim_make_hcase(VALUE mod, VALUE value, VALUE defolt) {
|
418
|
+
/* Allocates the hardware case. */
|
419
|
+
HCase hcase = (HCase)malloc(sizeof(HCaseS));
|
420
|
+
/* Set it up. */
|
421
|
+
hcase->kind = HCASE;
|
422
|
+
value_to_rcsim(ExpressionS,value,hcase->value);
|
423
|
+
hcase->num_whens = 0;
|
424
|
+
hcase->matches = NULL;
|
425
|
+
hcase->stmnts = NULL;
|
426
|
+
if (TYPE(defolt) == T_NIL)
|
427
|
+
hcase->defolt = NULL;
|
428
|
+
else
|
429
|
+
value_to_rcsim(StatementS,defolt,hcase->defolt);
|
430
|
+
/* Returns the C hardware case embedded into a ruby VALUE. */
|
431
|
+
VALUE res;
|
432
|
+
rcsim_to_value(HCaseS,hcase,res);
|
433
|
+
return res;
|
434
|
+
}
|
435
|
+
|
436
|
+
|
437
|
+
/* Creating a block C object. */
|
438
|
+
VALUE rcsim_make_block(VALUE mod, VALUE mode) {
|
439
|
+
/* Allocates the block. */
|
440
|
+
Block block = (Block)malloc(sizeof(BlockS));
|
441
|
+
/* Set it up. */
|
442
|
+
block->kind = BLOCK;
|
443
|
+
block->owner = NULL;
|
444
|
+
block->name = NULL;
|
445
|
+
block->num_inners = 0;
|
446
|
+
block->inners = NULL;
|
447
|
+
block->num_stmnts = 0;
|
448
|
+
block->stmnts = NULL;
|
449
|
+
block->mode = SYM2ID(mode) == id_PAR ? PAR : SEQ;
|
450
|
+
/* Returns the C block embedded into a ruby VALUE. */
|
451
|
+
VALUE res;
|
452
|
+
rcsim_to_value(BlockS,block,res);
|
453
|
+
return res;
|
454
|
+
}
|
455
|
+
|
456
|
+
|
457
|
+
/* Creating a numeric value C object. */
|
458
|
+
VALUE rcsim_make_value_numeric(VALUE mod, VALUE typeV, VALUE contentV) {
|
459
|
+
// /* Allocates the value. */
|
460
|
+
// Value value = get_value();
|
461
|
+
// /* Sets its type. */
|
462
|
+
// value_to_rcsim(TypeS,typeV,value->type);
|
463
|
+
/* Get the type. */
|
464
|
+
Type type;
|
465
|
+
value_to_rcsim(TypeS,typeV,type);
|
466
|
+
/* Create the value. */
|
467
|
+
Value value = make_value(type,0);
|
468
|
+
/* Set it to numeric. */
|
469
|
+
value->numeric = 1;
|
470
|
+
value->capacity = 0;
|
471
|
+
value->data_str = NULL;
|
472
|
+
value->data_int = NUM2LL(contentV);
|
473
|
+
/* Returns the C value embedded into a ruby VALUE. */
|
474
|
+
VALUE res;
|
475
|
+
rcsim_to_value(ValueS,value,res);
|
476
|
+
return res;
|
477
|
+
}
|
478
|
+
|
479
|
+
|
480
|
+
/* Creating a bitstring value C object. */
|
481
|
+
VALUE rcsim_make_value_bitstring(VALUE mod, VALUE typeV, VALUE contentV) {
|
482
|
+
// /* Allocates the value. */
|
483
|
+
// Value value = get_value();
|
484
|
+
// /* Sets its type. */
|
485
|
+
// value_to_rcsim(TypeS,type,value->type);
|
486
|
+
/* Get the type. */
|
487
|
+
Type type;
|
488
|
+
value_to_rcsim(TypeS,typeV,type);
|
489
|
+
/* Create the value. */
|
490
|
+
Value value = make_value(type,0);
|
491
|
+
// printf("Created from bitstring value=%p with type=%p\n",value,value->type);
|
492
|
+
// printf("and width=%llu\n",type_width(value->type));
|
493
|
+
/* Set it to bitstring. */
|
494
|
+
value->numeric = 0;
|
495
|
+
/* Generate the string of the content. */
|
496
|
+
char* str = StringValueCStr(contentV);
|
497
|
+
value->capacity = strlen(str)+1;
|
498
|
+
value->data_str = calloc(sizeof(char),value->capacity);
|
499
|
+
strcpy(value->data_str,str);
|
500
|
+
/* Returns the C value embedded into a ruby VALUE. */
|
501
|
+
VALUE res;
|
502
|
+
rcsim_to_value(ValueS,value,res);
|
503
|
+
return res;
|
504
|
+
}
|
505
|
+
|
506
|
+
|
507
|
+
/* Creating a cast C object. */
|
508
|
+
VALUE rcsim_make_cast(VALUE mod, VALUE type, VALUE child) {
|
509
|
+
/* Allocates the cast. */
|
510
|
+
Cast cast = (Cast)malloc(sizeof(CastS));
|
511
|
+
/* Set it up. */
|
512
|
+
cast->kind = CAST;
|
513
|
+
value_to_rcsim(TypeS,type,cast->type);
|
514
|
+
value_to_rcsim(ExpressionS,child,cast->child);
|
515
|
+
/* Returns the C cast embedded into a ruby VALUE. */
|
516
|
+
VALUE res;
|
517
|
+
rcsim_to_value(CastS,cast,res);
|
518
|
+
return res;
|
519
|
+
}
|
520
|
+
|
521
|
+
/* Creating a unary value C object. */
|
522
|
+
VALUE rcsim_make_unary(VALUE mod, VALUE type, VALUE operator, VALUE child) {
|
523
|
+
/* Allocates the unary. */
|
524
|
+
Unary unary= (Unary)malloc(sizeof(UnaryS));
|
525
|
+
/* Set it up. */
|
526
|
+
unary->kind = UNARY;
|
527
|
+
value_to_rcsim(TypeS,type,unary->type);
|
528
|
+
switch(sym_to_char(operator)) {
|
529
|
+
case (unsigned char)'~': unary->oper = not_value; break;
|
530
|
+
case (unsigned char)('-'+'@'*2): unary->oper = neg_value; break;
|
531
|
+
default: perror("Invalid operator for unary.");
|
532
|
+
}
|
533
|
+
value_to_rcsim(ExpressionS,child,unary->child);
|
534
|
+
/* Returns the C unary embedded into a ruby VALUE. */
|
535
|
+
VALUE res;
|
536
|
+
rcsim_to_value(UnaryS,unary,res);
|
537
|
+
return res;
|
538
|
+
}
|
539
|
+
|
540
|
+
/* Creating a binary value C object. */
|
541
|
+
VALUE rcsim_make_binary(VALUE mod, VALUE type, VALUE operator, VALUE left, VALUE right) {
|
542
|
+
/* Allocates the binary. */
|
543
|
+
Binary binary = (Binary)malloc(sizeof(BinaryS));
|
544
|
+
/* Set it up. */
|
545
|
+
binary->kind = BINARY;
|
546
|
+
value_to_rcsim(TypeS,type,binary->type);
|
547
|
+
switch(sym_to_char(operator)) {
|
548
|
+
case (unsigned char)'+': binary->oper = add_value; break;
|
549
|
+
case (unsigned char)'-': binary->oper = sub_value; break;
|
550
|
+
case (unsigned char)'*': binary->oper = mul_value; break;
|
551
|
+
case (unsigned char)'/': binary->oper = div_value; break;
|
552
|
+
case (unsigned char)'%': binary->oper = mod_value; break;
|
553
|
+
case (unsigned char)'&': binary->oper = and_value; break;
|
554
|
+
case (unsigned char)'|': binary->oper = or_value; break;
|
555
|
+
case (unsigned char)'^': binary->oper = xor_value; break;
|
556
|
+
case (unsigned char)('<'+'<'*2): binary->oper = shift_left_value; break;
|
557
|
+
case (unsigned char)('>'+'>'*2): binary->oper = shift_right_value; break;
|
558
|
+
case (unsigned char)('='+'='*2): binary->oper = equal_value_c; break;
|
559
|
+
case (unsigned char)('!'+'='*2): binary->oper = not_equal_value_c; break;
|
560
|
+
case (unsigned char)'<': binary->oper = lesser_value; break;
|
561
|
+
case (unsigned char)('<'+'='*2): binary->oper = lesser_equal_value; break;
|
562
|
+
case (unsigned char)'>': binary->oper = greater_value; break;
|
563
|
+
case (unsigned char)('>'+'='*2): binary->oper = greater_equal_value; break;
|
564
|
+
default: perror("Invalid operator for binary.");
|
565
|
+
}
|
566
|
+
value_to_rcsim(ExpressionS,left,binary->left);
|
567
|
+
value_to_rcsim(ExpressionS,right,binary->right);
|
568
|
+
/* Returns the C binary embedded into a ruby VALUE. */
|
569
|
+
VALUE res;
|
570
|
+
rcsim_to_value(BinaryS,binary,res);
|
571
|
+
return res;
|
572
|
+
}
|
573
|
+
|
574
|
+
/* Creating a select C object. */
|
575
|
+
VALUE rcsim_make_select(VALUE mod, VALUE type, VALUE sel) {
|
576
|
+
/* Allocates the select. */
|
577
|
+
Select select = (Select)malloc(sizeof(SelectS));
|
578
|
+
/* Set it up. */
|
579
|
+
select->kind = SELECT;
|
580
|
+
value_to_rcsim(TypeS,type,select->type);
|
581
|
+
value_to_rcsim(ExpressionS,sel,select->select);
|
582
|
+
select->num_choices = 0;
|
583
|
+
select->choices = NULL;
|
584
|
+
/* Returns the C select embedded into a ruby VALUE. */
|
585
|
+
VALUE res;
|
586
|
+
rcsim_to_value(SelectS,select,res);
|
587
|
+
return res;
|
588
|
+
}
|
589
|
+
|
590
|
+
/* Creating a concat C object. */
|
591
|
+
VALUE rcsim_make_concat(VALUE mod, VALUE type, VALUE dirV) {
|
592
|
+
/* Allocates the concat. */
|
593
|
+
Concat concat = (Concat)malloc(sizeof(ConcatS));
|
594
|
+
/* Set it up. */
|
595
|
+
concat->kind = CONCAT;
|
596
|
+
value_to_rcsim(TypeS,type,concat->type);
|
597
|
+
concat->num_exprs = 0;
|
598
|
+
concat->exprs = NULL;
|
599
|
+
concat->dir = rb_id2name(SYM2ID(dirV))[0]=='l' ? 1 : 0;
|
600
|
+
/* Returns the C concat embedded into a ruby VALUE. */
|
601
|
+
VALUE res;
|
602
|
+
rcsim_to_value(ConcatS,concat,res);
|
603
|
+
return res;
|
604
|
+
}
|
605
|
+
|
606
|
+
/* Creating a ref concat C object. */
|
607
|
+
VALUE rcsim_make_refConcat(VALUE mod, VALUE type, VALUE dirV) {
|
608
|
+
/* Allocates the ref concat. */
|
609
|
+
RefConcat refConcat = (RefConcat)malloc(sizeof(RefConcatS));
|
610
|
+
/* Set it up. */
|
611
|
+
refConcat->kind = REF_CONCAT;
|
612
|
+
value_to_rcsim(TypeS,type,refConcat->type);
|
613
|
+
refConcat->num_refs = 0;
|
614
|
+
refConcat->refs = NULL;
|
615
|
+
refConcat->dir = rb_id2name(SYM2ID(dirV))[0]=='l' ? 0 : 1;
|
616
|
+
/* Returns the C ref concat embedded into a ruby VALUE. */
|
617
|
+
VALUE res;
|
618
|
+
rcsim_to_value(RefConcatS,refConcat,res);
|
619
|
+
return res;
|
620
|
+
}
|
621
|
+
|
622
|
+
/* Creating a ref index C object. */
|
623
|
+
VALUE rcsim_make_refIndex(VALUE mod, VALUE type, VALUE index, VALUE ref) {
|
624
|
+
/* Allocates the ref index. */
|
625
|
+
RefIndex refIndex = (RefIndex)malloc(sizeof(RefIndexS));
|
626
|
+
/* Set it up. */
|
627
|
+
refIndex->kind = REF_INDEX;
|
628
|
+
value_to_rcsim(TypeS,type,refIndex->type);
|
629
|
+
value_to_rcsim(ExpressionS,index,refIndex->index);
|
630
|
+
value_to_rcsim(ReferenceS,ref,refIndex->ref);
|
631
|
+
/* Returns the C ref index embedded into a ruby VALUE. */
|
632
|
+
VALUE res;
|
633
|
+
rcsim_to_value(RefIndexS,refIndex,res);
|
634
|
+
return res;
|
635
|
+
}
|
636
|
+
|
637
|
+
/* Creating a ref range C object. */
|
638
|
+
VALUE rcsim_make_refRange(VALUE mod, VALUE type, VALUE first, VALUE last, VALUE ref) {
|
639
|
+
/* Allocates the ref range. */
|
640
|
+
RefRangeE refRange = (RefRangeE)malloc(sizeof(RefRangeES));
|
641
|
+
/* Set it up. */
|
642
|
+
refRange->kind = REF_RANGE;
|
643
|
+
value_to_rcsim(TypeS,type,refRange->type);
|
644
|
+
value_to_rcsim(ExpressionS,first,refRange->first);
|
645
|
+
value_to_rcsim(ExpressionS,last,refRange->last);
|
646
|
+
value_to_rcsim(ReferenceS,ref,refRange->ref);
|
647
|
+
/* Returns the C ref range embedded into a ruby VALUE. */
|
648
|
+
VALUE res;
|
649
|
+
rcsim_to_value(RefRangeES,refRange,res);
|
650
|
+
return res;
|
651
|
+
}
|
652
|
+
|
653
|
+
|
654
|
+
/* Creating a character string C object. */
|
655
|
+
VALUE rcsim_make_stringE(VALUE mod, VALUE strV) {
|
656
|
+
/* Allocates the string. */
|
657
|
+
StringE stringE = (StringE)malloc(sizeof(StringES));
|
658
|
+
/* Set it up. */
|
659
|
+
stringE->kind = STRINGE;
|
660
|
+
stringE->str = strdup(StringValueCStr(strV));
|
661
|
+
/* Returns the C character string embedded into a ruby VALUE. */
|
662
|
+
VALUE res;
|
663
|
+
rcsim_to_value(StringES,stringE,res);
|
664
|
+
return res;
|
665
|
+
}
|
666
|
+
|
667
|
+
/*#### Adding elements to C simulation objects. ####*/
|
668
|
+
|
669
|
+
/* Adds inputs to a C systemT. */
|
670
|
+
VALUE rcsim_add_systemT_inputs(VALUE mod, VALUE systemTV, VALUE sigVs) {
|
671
|
+
/* Get the C systemT from the Ruby value. */
|
672
|
+
SystemT systemT;
|
673
|
+
value_to_rcsim(SystemTS,systemTV,systemT);
|
674
|
+
// printf("Adding to systemT with kind=%d and name=%s\n",systemT->kind, systemT->name);
|
675
|
+
/* Prepare the size for the inputs. */
|
676
|
+
long num = RARRAY_LEN(sigVs);
|
677
|
+
long old_num = systemT->num_inputs;
|
678
|
+
systemT->num_inputs += num;
|
679
|
+
systemT->inputs=realloc(systemT->inputs,sizeof(SignalI)*systemT->num_inputs);
|
680
|
+
// printf("size=%d num=%i\n",malloc_size(systemT->inputs),systemT->num_inputs);
|
681
|
+
// printf("required size=%lu\n",sizeof(SignalI)*systemT->num_inputs);
|
682
|
+
/* Get and add the signals from the Ruby value. */
|
683
|
+
for(int i=0; i< num; ++i) {
|
684
|
+
SignalI sig;
|
685
|
+
value_to_rcsim(SignalIS,rb_ary_entry(sigVs,i),sig);
|
686
|
+
// printf("old_num+i=%ld\n",old_num+i);
|
687
|
+
systemT->inputs[old_num + i] = sig;
|
688
|
+
}
|
689
|
+
return systemTV;
|
690
|
+
}
|
691
|
+
|
692
|
+
/* Adds outputs to a C systemT. */
|
693
|
+
VALUE rcsim_add_systemT_outputs(VALUE mod, VALUE systemTV, VALUE sigVs) {
|
694
|
+
/* Get the C systemT from the Ruby value. */
|
695
|
+
SystemT systemT;
|
696
|
+
value_to_rcsim(SystemTS,systemTV,systemT);
|
697
|
+
/* Prepare the size for the outputs. */
|
698
|
+
long num = RARRAY_LEN(sigVs);
|
699
|
+
long old_num = systemT->num_outputs;
|
700
|
+
systemT->num_outputs += num;
|
701
|
+
systemT->outputs =realloc(systemT->outputs,sizeof(SignalI)*systemT->num_outputs);
|
702
|
+
/* Get and add the signals from the Ruby value. */
|
703
|
+
for(int i=0; i< num; ++i) {
|
704
|
+
SignalI sig;
|
705
|
+
value_to_rcsim(SignalIS,rb_ary_entry(sigVs,i),sig);
|
706
|
+
systemT->outputs[old_num + i] = sig;
|
707
|
+
}
|
708
|
+
return systemTV;
|
709
|
+
}
|
710
|
+
|
711
|
+
/* Adds inouts to a C systemT. */
|
712
|
+
VALUE rcsim_add_systemT_inouts(VALUE mod, VALUE systemTV, VALUE sigVs) {
|
713
|
+
/* Get the C systemT from the Ruby value. */
|
714
|
+
SystemT systemT;
|
715
|
+
value_to_rcsim(SystemTS,systemTV,systemT);
|
716
|
+
/* Prepare the size for the inouts. */
|
717
|
+
long num = RARRAY_LEN(sigVs);
|
718
|
+
long old_num = systemT->num_inouts;
|
719
|
+
systemT->num_inouts += num;
|
720
|
+
systemT->inouts =realloc(systemT->inouts,sizeof(SignalI)*systemT->num_inouts);
|
721
|
+
/* Get and add the signals from the Ruby value. */
|
722
|
+
for(int i=0; i< num; ++i) {
|
723
|
+
SignalI sig;
|
724
|
+
value_to_rcsim(SignalIS,rb_ary_entry(sigVs,i),sig);
|
725
|
+
systemT->inouts[old_num + i] = sig;
|
726
|
+
}
|
727
|
+
return systemTV;
|
728
|
+
}
|
729
|
+
|
730
|
+
/* Adds inners to a C scope. */
|
731
|
+
VALUE rcsim_add_scope_inners(VALUE mod, VALUE scopeV, VALUE sigVs) {
|
732
|
+
/* Get the C scope from the Ruby value. */
|
733
|
+
Scope scope;
|
734
|
+
value_to_rcsim(ScopeS,scopeV,scope);
|
735
|
+
/* Prepare the size for the inners. */
|
736
|
+
long num = RARRAY_LEN(sigVs);
|
737
|
+
long old_num = scope->num_inners;
|
738
|
+
scope->num_inners += num;
|
739
|
+
scope->inners = realloc(scope->inners,sizeof(SignalI)*scope->num_inners);
|
740
|
+
/* Get and add the signals from the Ruby value. */
|
741
|
+
for(int i=0; i< num; ++i) {
|
742
|
+
SignalI sig;
|
743
|
+
value_to_rcsim(SignalIS,rb_ary_entry(sigVs,i),sig);
|
744
|
+
scope->inners[old_num + i] = sig;
|
745
|
+
}
|
746
|
+
return scopeV;
|
747
|
+
}
|
748
|
+
|
749
|
+
/* Adds behaviors to a C scope. */
|
750
|
+
VALUE rcsim_add_scope_behaviors(VALUE mod, VALUE scopeV, VALUE behVs) {
|
751
|
+
/* Get the C scope from the Ruby value. */
|
752
|
+
Scope scope;
|
753
|
+
value_to_rcsim(ScopeS,scopeV,scope);
|
754
|
+
/* Prepare the size for the behaviors. */
|
755
|
+
long num = RARRAY_LEN(behVs);
|
756
|
+
long old_num = scope->num_behaviors;
|
757
|
+
scope->num_behaviors += num;
|
758
|
+
scope->behaviors = realloc(scope->behaviors,
|
759
|
+
sizeof(Behavior)*scope->num_behaviors);
|
760
|
+
/* Get and add the behaviors from the Ruby value. */
|
761
|
+
for(int i=0; i< num; ++i) {
|
762
|
+
Behavior beh;
|
763
|
+
value_to_rcsim(BehaviorS,rb_ary_entry(behVs,i),beh);
|
764
|
+
scope->behaviors[old_num + i] = beh;
|
765
|
+
}
|
766
|
+
return scopeV;
|
767
|
+
}
|
768
|
+
|
769
|
+
/* Adds system instances to a C scope. */
|
770
|
+
VALUE rcsim_add_scope_systemIs(VALUE mod, VALUE scopeV, VALUE sysVs) {
|
771
|
+
/* Get the C scope from the Ruby value. */
|
772
|
+
Scope scope;
|
773
|
+
value_to_rcsim(ScopeS,scopeV,scope);
|
774
|
+
/* Prepare the size for the system instances. */
|
775
|
+
long num = RARRAY_LEN(sysVs);
|
776
|
+
long old_num = scope->num_systemIs;
|
777
|
+
scope->num_systemIs += num;
|
778
|
+
scope->systemIs = realloc(scope->systemIs,
|
779
|
+
sizeof(SystemI)*scope->num_systemIs);
|
780
|
+
/* Get and add the system instances from the Ruby value. */
|
781
|
+
for(int i=0; i< num; ++i) {
|
782
|
+
SystemI sys;
|
783
|
+
value_to_rcsim(SystemIS,rb_ary_entry(sysVs,i),sys);
|
784
|
+
scope->systemIs[old_num + i] = sys;
|
785
|
+
}
|
786
|
+
return scopeV;
|
787
|
+
}
|
788
|
+
|
789
|
+
/* Adds sub scopes to a C scope. */
|
790
|
+
VALUE rcsim_add_scope_scopes(VALUE mod, VALUE scopeV, VALUE scpVs) {
|
791
|
+
/* Get the C scope from the Ruby value. */
|
792
|
+
Scope scope;
|
793
|
+
value_to_rcsim(ScopeS,scopeV,scope);
|
794
|
+
/* Prepare the size for the sub scopes. */
|
795
|
+
long num = RARRAY_LEN(scpVs);
|
796
|
+
long old_num = scope->num_scopes;
|
797
|
+
scope->num_scopes += num;
|
798
|
+
scope->scopes = realloc(scope->scopes,
|
799
|
+
sizeof(Scope)*scope->num_scopes);
|
800
|
+
/* Get and add the sub scopes from the Ruby value. */
|
801
|
+
for(int i=0; i< num; ++i) {
|
802
|
+
Scope scp;
|
803
|
+
value_to_rcsim(ScopeS,rb_ary_entry(scpVs,i),scp);
|
804
|
+
scope->scopes[old_num + i] = scp;
|
805
|
+
}
|
806
|
+
return scopeV;
|
807
|
+
}
|
808
|
+
|
809
|
+
/* Adds events to a C behavior. */
|
810
|
+
VALUE rcsim_add_behavior_events(VALUE mod, VALUE behaviorV, VALUE eventVs) {
|
811
|
+
/* Get the C behavior from the Ruby value. */
|
812
|
+
Behavior behavior;
|
813
|
+
value_to_rcsim(BehaviorS,behaviorV,behavior);
|
814
|
+
/* Prepare the size for the events. */
|
815
|
+
long num = RARRAY_LEN(eventVs);
|
816
|
+
long old_num = behavior->num_events;
|
817
|
+
behavior->num_events += num;
|
818
|
+
behavior->events = realloc(behavior->events,
|
819
|
+
sizeof(Event)*behavior->num_events);
|
820
|
+
/* Get and add the events from the Ruby value. */
|
821
|
+
for(int i=0; i< num; ++i) {
|
822
|
+
Event event;
|
823
|
+
value_to_rcsim(EventS,rb_ary_entry(eventVs,i),event);
|
824
|
+
behavior->events[old_num + i] = event;
|
825
|
+
/* Update the signal of the event to say it activates the behavior. */
|
826
|
+
SignalI sig = event->signal;
|
827
|
+
switch(event->edge) {
|
828
|
+
case ANYEDGE:
|
829
|
+
sig->num_any++;
|
830
|
+
sig->any = realloc(sig->any,sizeof(Object)*sig->num_any);
|
831
|
+
sig->any[sig->num_any-1] = (Object)behavior;
|
832
|
+
break;
|
833
|
+
case POSEDGE:
|
834
|
+
sig->num_pos++;
|
835
|
+
sig->pos = realloc(sig->pos,sizeof(Object)*sig->num_pos);
|
836
|
+
sig->pos[sig->num_pos-1] = (Object)behavior;
|
837
|
+
break;
|
838
|
+
case NEGEDGE:
|
839
|
+
sig->num_neg++;
|
840
|
+
sig->neg = realloc(sig->neg,sizeof(Object)*sig->num_neg);
|
841
|
+
sig->neg[sig->num_neg-1] = (Object)behavior;
|
842
|
+
break;
|
843
|
+
default:
|
844
|
+
perror("Invalid value for an edge.");
|
845
|
+
}
|
846
|
+
}
|
847
|
+
return behaviorV;
|
848
|
+
}
|
849
|
+
|
850
|
+
/* Adds alternate system types to a C system instance. */
|
851
|
+
VALUE rcsim_add_systemI_systemTs(VALUE mod, VALUE systemIV, VALUE sysVs) {
|
852
|
+
/* Get the C systemI from the Ruby value. */
|
853
|
+
SystemI systemI;
|
854
|
+
value_to_rcsim(SystemIS,systemIV,systemI);
|
855
|
+
/* Prepare the size for the alternate system types. */
|
856
|
+
long num = RARRAY_LEN(sysVs);
|
857
|
+
long old_num = systemI->num_systems;
|
858
|
+
systemI->num_systems += num;
|
859
|
+
systemI->systems=realloc(systemI->systems,sizeof(SystemT)*systemI->num_systems);
|
860
|
+
/* Get and add the alternate system types from the Ruby value. */
|
861
|
+
for(int i=0; i< num; ++i) {
|
862
|
+
SystemT sys;
|
863
|
+
value_to_rcsim(SystemTS,rb_ary_entry(sysVs,i),sys);
|
864
|
+
systemI->systems[old_num + i] = sys;
|
865
|
+
}
|
866
|
+
return systemIV;
|
867
|
+
}
|
868
|
+
|
869
|
+
/* Adds arguments to a C print. */
|
870
|
+
VALUE rcsim_add_print_args(VALUE mod, VALUE printV, VALUE argVs) {
|
871
|
+
/* Get the C print from the Ruby value. */
|
872
|
+
Print print;
|
873
|
+
value_to_rcsim(PrintS,printV,print);
|
874
|
+
/* Prepare the size for the arguments. */
|
875
|
+
long num = RARRAY_LEN(argVs);
|
876
|
+
long old_num = print->num_args;
|
877
|
+
print->num_args += num;
|
878
|
+
print->args = realloc(print->args,
|
879
|
+
sizeof(Expression)*print->num_args);
|
880
|
+
/* Get and add the arguments from the Ruby value. */
|
881
|
+
for(int i=0; i< num; ++i) {
|
882
|
+
Expression arg;
|
883
|
+
value_to_rcsim(ExpressionS,rb_ary_entry(argVs,i),arg);
|
884
|
+
print->args[old_num + i] = arg;
|
885
|
+
}
|
886
|
+
return printV;
|
887
|
+
}
|
888
|
+
|
889
|
+
/* Adds noifs to a C hardware if. */
|
890
|
+
VALUE rcsim_add_hif_noifs(VALUE mod, VALUE hifV, VALUE condVs, VALUE stmntVs) {
|
891
|
+
/* Get the C hardware if from the Ruby value. */
|
892
|
+
HIf hif;
|
893
|
+
value_to_rcsim(HIfS,hifV,hif);
|
894
|
+
/* Prepare the size for the noifs. */
|
895
|
+
long num = RARRAY_LEN(condVs);
|
896
|
+
long old_num = hif->num_noifs;
|
897
|
+
hif->num_noifs += num;
|
898
|
+
hif->noconds = realloc(hif->noconds, sizeof(Expression)*hif->num_noifs);
|
899
|
+
hif->nostmnts = realloc(hif->nostmnts, sizeof(Statement)*hif->num_noifs);
|
900
|
+
/* Get and add the noifs from the Ruby value. */
|
901
|
+
for(int i=0; i< num; ++i) {
|
902
|
+
Expression cond;
|
903
|
+
Statement stmnt;
|
904
|
+
value_to_rcsim(ExpressionS,rb_ary_entry(condVs,i),cond);
|
905
|
+
hif->noconds[old_num + i] = cond;
|
906
|
+
value_to_rcsim(StatementS,rb_ary_entry(stmntVs,i),stmnt);
|
907
|
+
hif->nostmnts[old_num + i] = stmnt;
|
908
|
+
}
|
909
|
+
return hifV;
|
910
|
+
}
|
911
|
+
|
912
|
+
/* Adds whens to a C hardware case. */
|
913
|
+
VALUE rcsim_add_hcase_whens(VALUE mod, VALUE hcaseV, VALUE matchVs, VALUE stmntVs) {
|
914
|
+
/* Get the C hardware case from the Ruby value. */
|
915
|
+
HCase hcase;
|
916
|
+
value_to_rcsim(HCaseS,hcaseV,hcase);
|
917
|
+
/* Prepare the size for the noifs. */
|
918
|
+
long num = RARRAY_LEN(matchVs);
|
919
|
+
long old_num = hcase->num_whens;
|
920
|
+
hcase->num_whens += num;
|
921
|
+
hcase->matches = realloc(hcase->matches,
|
922
|
+
sizeof(Expression)*hcase->num_whens);
|
923
|
+
hcase->stmnts = realloc(hcase->stmnts,
|
924
|
+
sizeof(Statement)*hcase->num_whens);
|
925
|
+
/* Get and add the whens from the Ruby value. */
|
926
|
+
for(int i=0; i< num; ++i) {
|
927
|
+
Expression match;
|
928
|
+
Statement stmnt;
|
929
|
+
value_to_rcsim(ExpressionS,rb_ary_entry(matchVs,i),match);
|
930
|
+
hcase->matches[old_num + i] = match;
|
931
|
+
value_to_rcsim(StatementS,rb_ary_entry(stmntVs,i),stmnt);
|
932
|
+
hcase->stmnts[old_num + i] = stmnt;
|
933
|
+
}
|
934
|
+
return hcaseV;
|
935
|
+
}
|
936
|
+
|
937
|
+
/* Adds inners to a C block. */
|
938
|
+
VALUE rcsim_add_block_inners(VALUE mod, VALUE blockV, VALUE sigVs) {
|
939
|
+
/* Get the C block from the Ruby value. */
|
940
|
+
Block block;
|
941
|
+
value_to_rcsim(BlockS,blockV,block);
|
942
|
+
/* Prepare the size for the inners. */
|
943
|
+
long num = RARRAY_LEN(sigVs);
|
944
|
+
long old_num = block->num_inners;
|
945
|
+
block->num_inners += num;
|
946
|
+
block->inners = realloc(block->inners,sizeof(SignalI)*block->num_inners);
|
947
|
+
/* Get and add the signals from the Ruby value. */
|
948
|
+
for(int i=0; i< num; ++i) {
|
949
|
+
SignalI sig;
|
950
|
+
value_to_rcsim(SignalIS,rb_ary_entry(sigVs,i),sig);
|
951
|
+
block->inners[old_num + i] = sig;
|
952
|
+
}
|
953
|
+
return blockV;
|
954
|
+
}
|
955
|
+
|
956
|
+
/* Adds statements to a C block. */
|
957
|
+
VALUE rcsim_add_block_statements(VALUE mod, VALUE blockV, VALUE stmntVs) {
|
958
|
+
/* Get the C block from the Ruby value. */
|
959
|
+
Block block;
|
960
|
+
value_to_rcsim(BlockS,blockV,block);
|
961
|
+
/* Prepare the size for the statements. */
|
962
|
+
long num = RARRAY_LEN(stmntVs);
|
963
|
+
long old_num = block->num_stmnts;
|
964
|
+
block->num_stmnts += num;
|
965
|
+
block->stmnts = realloc(block->stmnts,sizeof(Statement)*block->num_stmnts);
|
966
|
+
/* Get and add the statements from the Ruby value. */
|
967
|
+
for(int i=0; i< num; ++i) {
|
968
|
+
Statement stmnt;
|
969
|
+
value_to_rcsim(StatementS,rb_ary_entry(stmntVs,i),stmnt);
|
970
|
+
block->stmnts[old_num + i] = stmnt;
|
971
|
+
}
|
972
|
+
return blockV;
|
973
|
+
}
|
974
|
+
|
975
|
+
/* Adds choices to a C select. */
|
976
|
+
VALUE rcsim_add_select_choices(VALUE mod, VALUE selectV, VALUE choiceVs) {
|
977
|
+
/* Get the C select from the Ruby value. */
|
978
|
+
Select select;
|
979
|
+
value_to_rcsim(SelectS,selectV,select);
|
980
|
+
/* Prepare the size for the choices. */
|
981
|
+
long num = RARRAY_LEN(choiceVs);
|
982
|
+
long old_num = select->num_choices;
|
983
|
+
select->num_choices += num;
|
984
|
+
select->choices = realloc(select->choices,sizeof(Expression)*select->num_choices);
|
985
|
+
/* Get and add the choices from the Ruby value. */
|
986
|
+
for(int i=0; i< num; ++i) {
|
987
|
+
Expression choice;
|
988
|
+
value_to_rcsim(ExpressionS,rb_ary_entry(choiceVs,i),choice);
|
989
|
+
select->choices[old_num + i] = choice;
|
990
|
+
}
|
991
|
+
return selectV;
|
992
|
+
}
|
993
|
+
|
994
|
+
/* Adds expressions to a C concat. */
|
995
|
+
VALUE rcsim_add_concat_expressions(VALUE mod, VALUE concatV, VALUE exprVs) {
|
996
|
+
/* Get the C concat from the Ruby value. */
|
997
|
+
Concat concat;
|
998
|
+
value_to_rcsim(ConcatS,concatV,concat);
|
999
|
+
/* Prepare the size for the expressions. */
|
1000
|
+
long num = RARRAY_LEN(exprVs);
|
1001
|
+
long old_num = concat->num_exprs;
|
1002
|
+
// printf("add_concat_expressions with num=%li old_num=%li\n",num,old_num);
|
1003
|
+
concat->num_exprs += num;
|
1004
|
+
concat->exprs = realloc(concat->exprs,sizeof(Expression)*concat->num_exprs);
|
1005
|
+
/* Get and add the expressions from the Ruby value. */
|
1006
|
+
for(int i=0; i< num; ++i) {
|
1007
|
+
Expression expr;
|
1008
|
+
value_to_rcsim(ExpressionS,rb_ary_entry(exprVs,i),expr);
|
1009
|
+
// printf("Adding expression with type width=%llu\n",type_width(expr->type));
|
1010
|
+
concat->exprs[old_num + i] = expr;
|
1011
|
+
}
|
1012
|
+
return concatV;
|
1013
|
+
}
|
1014
|
+
|
1015
|
+
/* Adds references to a C ref concat. */
|
1016
|
+
VALUE rcsim_add_refConcat_refs(VALUE mod, VALUE refConcatV, VALUE refVs) {
|
1017
|
+
/* Get the C refConcat from the Ruby value. */
|
1018
|
+
RefConcat refConcat;
|
1019
|
+
value_to_rcsim(RefConcatS,refConcatV,refConcat);
|
1020
|
+
/* Prepare the size for the references. */
|
1021
|
+
long num = RARRAY_LEN(refVs);
|
1022
|
+
long old_num = refConcat->num_refs;
|
1023
|
+
refConcat->num_refs += num;
|
1024
|
+
refConcat->refs = realloc(refConcat->refs,sizeof(Reference)*refConcat->num_refs);
|
1025
|
+
/* Get and add the references from the Ruby value. */
|
1026
|
+
for(int i=0; i< num; ++i) {
|
1027
|
+
Reference ref;
|
1028
|
+
value_to_rcsim(ReferenceS,rb_ary_entry(refVs,i),ref);
|
1029
|
+
refConcat->refs[old_num + i] = ref;
|
1030
|
+
}
|
1031
|
+
return refConcatV;
|
1032
|
+
}
|
1033
|
+
|
1034
|
+
|
1035
|
+
/*#### Modifying C simulation objects. ####*/
|
1036
|
+
|
1037
|
+
/** Sets the owner for a C simulation object. */
|
1038
|
+
VALUE rcsim_set_owner(VALUE mod, VALUE objV, VALUE ownerV) {
|
1039
|
+
/* Get the C object from the Ruby value. */
|
1040
|
+
Object obj;
|
1041
|
+
value_to_rcsim(ObjectS,objV,obj);
|
1042
|
+
/* Get the C owner from the Ruby value. */
|
1043
|
+
Object owner;
|
1044
|
+
value_to_rcsim(ObjectS,ownerV,owner);
|
1045
|
+
/* Set the owner. */
|
1046
|
+
obj->owner = owner;
|
1047
|
+
return objV;
|
1048
|
+
}
|
1049
|
+
|
1050
|
+
/** Sets the scope for a C system type. */
|
1051
|
+
VALUE rcsim_set_systemT_scope(VALUE mod, VALUE systemTV, VALUE scopeV) {
|
1052
|
+
/* Get the C system type from the Ruby value. */
|
1053
|
+
SystemT systemT;
|
1054
|
+
value_to_rcsim(SystemTS,systemTV,systemT);
|
1055
|
+
/* Get the C scope from the Ruby value. */
|
1056
|
+
Scope scope;
|
1057
|
+
value_to_rcsim(ScopeS,scopeV,scope);
|
1058
|
+
/* Set the scope. */
|
1059
|
+
systemT->scope = scope;
|
1060
|
+
return systemTV;
|
1061
|
+
}
|
1062
|
+
|
1063
|
+
/** Sets the block for a C behavior. */
|
1064
|
+
VALUE rcsim_set_behavior_block(VALUE mod, VALUE behaviorV, VALUE blockV) {
|
1065
|
+
/* Get the C behavior from the Ruby value. */
|
1066
|
+
Behavior behavior;
|
1067
|
+
value_to_rcsim(BehaviorS,behaviorV,behavior);
|
1068
|
+
/* Get the C block from the Ruby value. */
|
1069
|
+
Block block;
|
1070
|
+
value_to_rcsim(BlockS,blockV,block);
|
1071
|
+
/* Set the block. */
|
1072
|
+
behavior->block = block;
|
1073
|
+
return behaviorV;
|
1074
|
+
}
|
1075
|
+
|
1076
|
+
/** Sets the value for a C signal. */
|
1077
|
+
VALUE rcsim_set_signal_value(VALUE mod, VALUE signalV, VALUE exprV) {
|
1078
|
+
/* Get the C signal from the Ruby value. */
|
1079
|
+
SignalI signal;
|
1080
|
+
value_to_rcsim(SignalIS,signalV,signal);
|
1081
|
+
// printf("rc_sim_set_signal_value for signal=%s\n",signal->name);
|
1082
|
+
/* Get the C expression from the Ruby value. */
|
1083
|
+
Expression expr;
|
1084
|
+
value_to_rcsim(ExpressionS,exprV,expr);
|
1085
|
+
/* Compute the value from it. */
|
1086
|
+
// Value value = calc_expression(expr);
|
1087
|
+
Value value = get_value();
|
1088
|
+
value = calc_expression(expr,value);
|
1089
|
+
/* Copies the value. */
|
1090
|
+
signal->f_value = copy_value(value,signal->f_value);
|
1091
|
+
free_value();
|
1092
|
+
return signalV;
|
1093
|
+
}
|
1094
|
+
|
1095
|
+
|
1096
|
+
/** Starts the C-Ruby hybrid simulation.
|
1097
|
+
* @param systemTV the top system type.
|
1098
|
+
* @param name the name of the simulation.
|
1099
|
+
* @param vcd tells if the vcd generation is used or not. */
|
1100
|
+
VALUE rcsim_main(VALUE mod, VALUE systemTV, VALUE name, VALUE vcd) {
|
1101
|
+
/* Get the C system type from the Ruby value. */
|
1102
|
+
SystemT systemT;
|
1103
|
+
value_to_rcsim(SystemTS,systemTV,systemT);
|
1104
|
+
/* Set it as the top of the simulator. */
|
1105
|
+
top_system = systemT;
|
1106
|
+
/* Enable it. */
|
1107
|
+
set_enable_system(systemT,1);
|
1108
|
+
/* Starts the simulation. */
|
1109
|
+
if (TYPE(vcd) == T_TRUE)
|
1110
|
+
hruby_sim_core(StringValueCStr(name),init_vcd_visualizer,-1);
|
1111
|
+
else
|
1112
|
+
hruby_sim_core(StringValueCStr(name),init_default_visualizer,-1);
|
1113
|
+
return systemTV;
|
1114
|
+
}
|
1115
|
+
|
1116
|
+
|
1117
|
+
|
1118
|
+
|
1119
|
+
/** The initialization of the C-part of the C-Ruby hybrid HDLRuby simulator. */
|
1120
|
+
void Init_hruby_sim() {
|
1121
|
+
/* Generate the ID of the symbols used in the simulator. */
|
1122
|
+
make_sym_IDs();
|
1123
|
+
/* Create the module for C-Ruby interface. */
|
1124
|
+
VALUE mod = rb_define_module("RCSimCinterface");
|
1125
|
+
|
1126
|
+
/* Create the class that wraps C pointers. */
|
1127
|
+
RCSimPointer = rb_define_class("RCSimPointer",rb_cObject);
|
1128
|
+
|
1129
|
+
/* Add the interface methods. */
|
1130
|
+
/* Getting the C simulation type objects. */
|
1131
|
+
rb_define_singleton_method(mod,"rcsim_get_type_bit",rcsim_get_type_bit,0);
|
1132
|
+
rb_define_singleton_method(mod,"rcsim_get_type_signed",rcsim_get_type_signed,0);
|
1133
|
+
rb_define_singleton_method(mod,"rcsim_get_type_vector",rcsim_get_type_vector,2);
|
1134
|
+
/* Creating the C simulation objects. */
|
1135
|
+
rb_define_singleton_method(mod,"rcsim_make_systemT",rcsim_make_systemT,1);
|
1136
|
+
rb_define_singleton_method(mod,"rcsim_make_scope",rcsim_make_scope,1);
|
1137
|
+
rb_define_singleton_method(mod,"rcsim_make_behavior",rcsim_make_behavior,1);
|
1138
|
+
rb_define_singleton_method(mod,"rcsim_make_event",rcsim_make_event,2);
|
1139
|
+
rb_define_singleton_method(mod,"rcsim_make_signal",rcsim_make_signal,2);
|
1140
|
+
rb_define_singleton_method(mod,"rcsim_make_systemI",rcsim_make_systemI,2);
|
1141
|
+
rb_define_singleton_method(mod,"rcsim_make_transmit",rcsim_make_transmit,2);
|
1142
|
+
rb_define_singleton_method(mod,"rcsim_make_print",rcsim_make_print,0);
|
1143
|
+
rb_define_singleton_method(mod,"rcsim_make_timeWait",rcsim_make_timeWait,2);
|
1144
|
+
rb_define_singleton_method(mod,"rcsim_make_timeTerminate",rcsim_make_timeTerminate,0);
|
1145
|
+
rb_define_singleton_method(mod,"rcsim_make_hif",rcsim_make_hif,3);
|
1146
|
+
rb_define_singleton_method(mod,"rcsim_make_hcase",rcsim_make_hcase,2);
|
1147
|
+
rb_define_singleton_method(mod,"rcsim_make_block",rcsim_make_block,1);
|
1148
|
+
rb_define_singleton_method(mod,"rcsim_make_value_numeric",rcsim_make_value_numeric,2);
|
1149
|
+
rb_define_singleton_method(mod,"rcsim_make_value_bitstring",rcsim_make_value_bitstring,2);
|
1150
|
+
rb_define_singleton_method(mod,"rcsim_make_cast",rcsim_make_cast,2);
|
1151
|
+
rb_define_singleton_method(mod,"rcsim_make_unary",rcsim_make_unary,3);
|
1152
|
+
rb_define_singleton_method(mod,"rcsim_make_binary",rcsim_make_binary,4);
|
1153
|
+
rb_define_singleton_method(mod,"rcsim_make_select",rcsim_make_select,2);
|
1154
|
+
rb_define_singleton_method(mod,"rcsim_make_concat",rcsim_make_concat,2);
|
1155
|
+
rb_define_singleton_method(mod,"rcsim_make_refConcat",rcsim_make_refConcat,1);
|
1156
|
+
rb_define_singleton_method(mod,"rcsim_make_refIndex",rcsim_make_refIndex,3);
|
1157
|
+
rb_define_singleton_method(mod,"rcsim_make_refRange",rcsim_make_refRange,4);
|
1158
|
+
rb_define_singleton_method(mod,"rcsim_make_stringE",rcsim_make_stringE,1);
|
1159
|
+
/* Adding elements to C simulation objects. */
|
1160
|
+
rb_define_singleton_method(mod,"rcsim_add_systemT_inputs",rcsim_add_systemT_inputs,2);
|
1161
|
+
rb_define_singleton_method(mod,"rcsim_add_systemT_outputs",rcsim_add_systemT_outputs,2);
|
1162
|
+
rb_define_singleton_method(mod,"rcsim_add_systemT_inouts",rcsim_add_systemT_inouts,2);
|
1163
|
+
rb_define_singleton_method(mod,"rcsim_add_scope_inners",rcsim_add_scope_inners,2);
|
1164
|
+
rb_define_singleton_method(mod,"rcsim_add_scope_behaviors",rcsim_add_scope_behaviors,2);
|
1165
|
+
rb_define_singleton_method(mod,"rcsim_add_scope_systemIs",rcsim_add_scope_systemIs,2);
|
1166
|
+
rb_define_singleton_method(mod,"rcsim_add_scope_scopes",rcsim_add_scope_scopes,2);
|
1167
|
+
rb_define_singleton_method(mod,"rcsim_add_behavior_events",rcsim_add_behavior_events,2);
|
1168
|
+
rb_define_singleton_method(mod,"rcsim_add_systemI_systemTs",rcsim_add_systemI_systemTs,2);
|
1169
|
+
rb_define_singleton_method(mod,"rcsim_add_print_args",rcsim_add_print_args,2);
|
1170
|
+
rb_define_singleton_method(mod,"rcsim_add_hif_noifs",rcsim_add_hif_noifs,3);
|
1171
|
+
rb_define_singleton_method(mod,"rcsim_add_hcase_whens",rcsim_add_hcase_whens,3);
|
1172
|
+
rb_define_singleton_method(mod,"rcsim_add_block_inners",rcsim_add_block_inners,2);
|
1173
|
+
rb_define_singleton_method(mod,"rcsim_add_block_statements",rcsim_add_block_statements,2);
|
1174
|
+
rb_define_singleton_method(mod,"rcsim_add_select_choices",rcsim_add_select_choices,2);
|
1175
|
+
rb_define_singleton_method(mod,"rcsim_add_concat_expressions",rcsim_add_concat_expressions,2);
|
1176
|
+
rb_define_singleton_method(mod,"rcsim_add_refConcat_refs",rcsim_add_refConcat_refs,2);
|
1177
|
+
/* Modifying C simulation objects. */
|
1178
|
+
rb_define_singleton_method(mod,"rcsim_set_owner",rcsim_set_owner,2);
|
1179
|
+
rb_define_singleton_method(mod,"rcsim_set_systemT_scope",rcsim_set_systemT_scope,2);
|
1180
|
+
rb_define_singleton_method(mod,"rcsim_set_behavior_block",rcsim_set_behavior_block,2);
|
1181
|
+
rb_define_singleton_method(mod,"rcsim_set_signal_value",rcsim_set_signal_value,2);
|
1182
|
+
/* Starting the simulation. */
|
1183
|
+
rb_define_singleton_method(mod,"rcsim_main",rcsim_main,3);
|
1184
|
+
|
1185
|
+
}
|
1186
|
+
|
1187
|
+
|
1188
|
+
#endif
|