HDLRuby 3.1.0 → 3.3.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.html +2330 -2670
- data/README.md +400 -100
- data/ext/hruby_sim/hruby_rcsim_build.c +402 -3
- data/ext/hruby_sim/hruby_sim.h +2 -1
- data/ext/hruby_sim/hruby_sim_calc.c +34 -7
- data/ext/hruby_sim/hruby_sim_core.c +15 -5
- data/ext/hruby_sim/hruby_sim_tree_calc.c +112 -23
- data/lib/HDLRuby/hdr_samples/c_program/echo.c +33 -0
- data/lib/HDLRuby/hdr_samples/comparison_bench.rb +2 -2
- data/lib/HDLRuby/hdr_samples/counter_bench.rb +1 -1
- data/lib/HDLRuby/hdr_samples/counter_dff_bench.rb +8 -7
- data/lib/HDLRuby/hdr_samples/dff_properties.rb +2 -0
- data/lib/HDLRuby/hdr_samples/enum_as_param.rb +52 -0
- data/lib/HDLRuby/hdr_samples/linear_test.rb +2 -0
- data/lib/HDLRuby/hdr_samples/logic_bench.rb +6 -0
- data/lib/HDLRuby/hdr_samples/mei8.rb +6 -6
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +6 -6
- data/lib/HDLRuby/hdr_samples/memory_test.rb +2 -0
- data/lib/HDLRuby/hdr_samples/named_sub.rb +9 -5
- data/lib/HDLRuby/hdr_samples/ram.rb +7 -6
- data/lib/HDLRuby/hdr_samples/ruby_fir_hw.rb +2 -0
- data/lib/HDLRuby/hdr_samples/ruby_program/echo.rb +9 -0
- data/lib/HDLRuby/hdr_samples/ruby_program/stdrw.rb +6 -0
- data/lib/HDLRuby/hdr_samples/ruby_program/sw_cpu_terminal.rb +614 -0
- data/lib/HDLRuby/hdr_samples/ruby_program/sw_inc_mem.rb +32 -0
- data/lib/HDLRuby/hdr_samples/ruby_program/sw_log.rb +33 -0
- data/lib/HDLRuby/hdr_samples/struct.rb +15 -3
- data/lib/HDLRuby/hdr_samples/with_board.rb +63 -0
- data/lib/HDLRuby/hdr_samples/with_bram.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_bram_frame_stack.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_bram_stack.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_channel.rb +2 -0
- data/lib/HDLRuby/hdr_samples/with_channel_other.rb +2 -0
- data/lib/HDLRuby/hdr_samples/with_class.rb +3 -1
- data/lib/HDLRuby/hdr_samples/with_clocks.rb +42 -0
- data/lib/HDLRuby/hdr_samples/with_connector.rb +2 -0
- data/lib/HDLRuby/hdr_samples/with_connector_memory.rb +2 -0
- data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +6 -0
- data/lib/HDLRuby/hdr_samples/with_fixpoint_adv.rb +73 -0
- data/lib/HDLRuby/hdr_samples/with_leftright.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_of.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_program_c.rb +28 -0
- data/lib/HDLRuby/hdr_samples/with_program_ruby.rb +28 -0
- data/lib/HDLRuby/hdr_samples/with_program_ruby_cpu.rb +234 -0
- data/lib/HDLRuby/hdr_samples/with_program_ruby_io.rb +23 -0
- data/lib/HDLRuby/hdr_samples/with_program_ruby_mem.rb +58 -0
- data/lib/HDLRuby/hdr_samples/with_program_ruby_threads.rb +56 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer.rb +17 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer_channel.rb +58 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer_enumerable.rb +10 -0
- data/lib/HDLRuby/hdr_samples/with_sequencer_enumerator.rb +18 -4
- data/lib/HDLRuby/hdr_samples/with_sequencer_func.rb +2 -4
- data/lib/HDLRuby/hdr_samples/with_sequencer_sync.rb +2 -1
- data/lib/HDLRuby/hdrcc.rb +72 -21
- data/lib/HDLRuby/hruby_error.rb +13 -0
- data/lib/HDLRuby/hruby_high.rb +125 -26
- data/lib/HDLRuby/hruby_low.rb +171 -3
- data/lib/HDLRuby/hruby_low2programs.rb +47 -0
- data/lib/HDLRuby/hruby_low_resolve.rb +3 -2
- data/lib/HDLRuby/hruby_low_without_namespace.rb +133 -5
- data/lib/HDLRuby/hruby_low_without_subsignals.rb +1 -1
- data/lib/HDLRuby/hruby_rcsim.rb +113 -6
- data/lib/HDLRuby/hruby_serializer.rb +2 -1
- data/lib/HDLRuby/hruby_verilog.rb +94 -20
- data/lib/HDLRuby/hruby_verilog_name.rb +3 -17
- data/lib/HDLRuby/std/clocks.rb +118 -50
- data/lib/HDLRuby/std/fixpoint.rb +2 -2
- data/lib/HDLRuby/std/function_generator.rb +1 -1
- data/lib/HDLRuby/std/linear.rb +7 -7
- data/lib/HDLRuby/std/sequencer.rb +263 -13
- data/lib/HDLRuby/std/sequencer_channel.rb +90 -0
- data/lib/HDLRuby/std/sequencer_func.rb +28 -15
- data/lib/HDLRuby/std/std.rb +6 -0
- data/lib/HDLRuby/ui/hruby_board.rb +1079 -0
- data/lib/HDLRuby/version.rb +1 -1
- data/lib/c/Rakefile +8 -0
- data/lib/c/cHDL.h +12 -0
- data/lib/c/extconf.rb +7 -0
- data/lib/rubyHDL.rb +33 -0
- data/tuto/gui_accum.png +0 -0
- data/tuto/gui_board.png +0 -0
- data/tuto/tutorial_sw.html +2263 -1890
- data/tuto/tutorial_sw.md +957 -62
- metadata +43 -5
- data/README.pdf +0 -0
- data/tuto/tutorial_sw.pdf +0 -0
|
@@ -6,9 +6,16 @@
|
|
|
6
6
|
#include <string.h>
|
|
7
7
|
#include <limits.h>
|
|
8
8
|
|
|
9
|
+
#if defined(_WIN32) || defined(_WIN64)
|
|
10
|
+
#include <windows.h>
|
|
11
|
+
#include <direct.h>
|
|
12
|
+
#else
|
|
13
|
+
#include <dlfcn.h>
|
|
14
|
+
#endif
|
|
15
|
+
|
|
9
16
|
#include <ruby.h>
|
|
10
|
-
#include "extconf.h"
|
|
11
17
|
|
|
18
|
+
#include "extconf.h"
|
|
12
19
|
#include "hruby_sim.h"
|
|
13
20
|
|
|
14
21
|
// #if defined(_WIN32) || defined(_WIN64)
|
|
@@ -72,7 +79,10 @@
|
|
|
72
79
|
// rcsim_wrapper(RefIndex);
|
|
73
80
|
// rcsim_wrapper(RefRange);
|
|
74
81
|
|
|
75
|
-
static VALUE RCSimPointer;
|
|
82
|
+
static VALUE RCSimPointer; // The C pointer type for Ruby.
|
|
83
|
+
static VALUE RCSimCinterface; // The RCSim Ruby module for C.
|
|
84
|
+
static VALUE RCSimCports; // The RCSim table of C ports.
|
|
85
|
+
// static VALUE RubyHDL; // The interface for Ruby programs.
|
|
76
86
|
|
|
77
87
|
#define rcsim_to_value(TYPE,POINTER,VALUE) \
|
|
78
88
|
(VALUE) = Data_Wrap_Struct(RCSimPointer, 0, 0, (POINTER))
|
|
@@ -376,6 +386,123 @@ VALUE rcsim_make_systemI(VALUE mod, VALUE name, VALUE systemT) {
|
|
|
376
386
|
}
|
|
377
387
|
|
|
378
388
|
|
|
389
|
+
void ruby_function_wrap(Code);
|
|
390
|
+
|
|
391
|
+
/* Creating a system code C object.
|
|
392
|
+
* Note: HDLRuby Code object are actually refactored to Program object,
|
|
393
|
+
* but the low-level simulation still use Code as data structure.
|
|
394
|
+
* Hence, it may change in the future. */
|
|
395
|
+
VALUE rcsim_make_code(VALUE mod, VALUE lang, VALUE funcname) {
|
|
396
|
+
// printf("rcsim_make_code\n");
|
|
397
|
+
/* Allocates the code. */
|
|
398
|
+
Code code = (Code)malloc(sizeof(CodeS));
|
|
399
|
+
// printf("code=%p\n",code);
|
|
400
|
+
/* Set it up. */
|
|
401
|
+
code->kind = CODE;
|
|
402
|
+
code->owner = NULL;
|
|
403
|
+
code->name = strdup(StringValueCStr(funcname));
|
|
404
|
+
// printf("code->name=%p\n",code->name);
|
|
405
|
+
code->num_events = 0;
|
|
406
|
+
code->events = NULL;
|
|
407
|
+
code->function = NULL;
|
|
408
|
+
char* langStr = StringValueCStr(lang);
|
|
409
|
+
if(strncmp(langStr,"ruby",4) == 0) {
|
|
410
|
+
/* Ruby function. */
|
|
411
|
+
code->function = ruby_function_wrap;
|
|
412
|
+
} else if (strncmp(langStr,"c",1) == 0) {
|
|
413
|
+
/* C or C-compatible dynamically compiled code: it will be loaded
|
|
414
|
+
* afterward */
|
|
415
|
+
code->function = NULL;
|
|
416
|
+
} else {
|
|
417
|
+
/* Other language function. */
|
|
418
|
+
fprintf(stderr,"Unsupported language.");
|
|
419
|
+
exit(-1);
|
|
420
|
+
}
|
|
421
|
+
code->enabled = 0;
|
|
422
|
+
code->activated = 0;
|
|
423
|
+
/* Returns the C code embedded into a ruby VALUE. */
|
|
424
|
+
VALUE res;
|
|
425
|
+
rcsim_to_value(CodeS,code,res);
|
|
426
|
+
return res;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
#if defined(_WIN32) || defined(_WIN64)
|
|
433
|
+
/** Loads a C program dynamic library (called from HDLRuby) for a code. */
|
|
434
|
+
VALUE rcsim_load_c(VALUE mod, VALUE codeV, VALUE libnameV, VALUE funcnameV) {
|
|
435
|
+
char* libname;
|
|
436
|
+
char* funcname;
|
|
437
|
+
Code code;
|
|
438
|
+
HINSTANCE handle;
|
|
439
|
+
|
|
440
|
+
libname = StringValueCStr(libnameV);
|
|
441
|
+
funcname = StringValueCStr(funcnameV);
|
|
442
|
+
|
|
443
|
+
char path[1024];
|
|
444
|
+
|
|
445
|
+
if (getcwd(path, sizeof(path)) != NULL) {
|
|
446
|
+
printf("Current working directory: %s\n", path);
|
|
447
|
+
} else {
|
|
448
|
+
perror("getcwd error");
|
|
449
|
+
return 1;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
if(strlen(path) + strlen(libname) >= 1023) {
|
|
453
|
+
fprintf(stderr,"Path too long for loading c program.\n");
|
|
454
|
+
}
|
|
455
|
+
strcat(path,"/");
|
|
456
|
+
strcat(path,libname);
|
|
457
|
+
// printf("Loading c program at: %s\n",path);
|
|
458
|
+
|
|
459
|
+
/* Get the code. */
|
|
460
|
+
value_to_rcsim(CodeS,codeV,code);
|
|
461
|
+
/* Load the library. */
|
|
462
|
+
handle = LoadLibrary(TEXT(path));
|
|
463
|
+
if (handle == NULL) {
|
|
464
|
+
fprintf(stderr,"Unable to open program library at: %s\n",path);
|
|
465
|
+
DWORD dwError = GetLastError();
|
|
466
|
+
fprintf(stderr,"LoadLibrary failed with error code %ld\n", dwError);
|
|
467
|
+
exit(-1);
|
|
468
|
+
}
|
|
469
|
+
code->function = GetProcAddress(handle,funcname);
|
|
470
|
+
if (code->function == NULL) {
|
|
471
|
+
fprintf(stderr,"Unable to get function: %s\n",code->name);
|
|
472
|
+
exit(-1);
|
|
473
|
+
}
|
|
474
|
+
return codeV;
|
|
475
|
+
}
|
|
476
|
+
#else
|
|
477
|
+
/** Loads a C program dynamic library (called from HDLRuby) for a code. */
|
|
478
|
+
VALUE rcsim_load_c(VALUE mod, VALUE codeV, VALUE libnameV, VALUE funcnameV) {
|
|
479
|
+
char* libname;
|
|
480
|
+
char* funcname;
|
|
481
|
+
Code code;
|
|
482
|
+
void* handle;
|
|
483
|
+
|
|
484
|
+
libname = StringValueCStr(libnameV);
|
|
485
|
+
funcname = StringValueCStr(funcnameV);
|
|
486
|
+
|
|
487
|
+
/* Get the code. */
|
|
488
|
+
value_to_rcsim(CodeS,codeV,code);
|
|
489
|
+
/* Load the library. */
|
|
490
|
+
handle = dlopen(libname,RTLD_NOW | RTLD_GLOBAL);
|
|
491
|
+
if (handle == NULL) {
|
|
492
|
+
fprintf(stderr,"Unable to open program: %s\n",dlerror());
|
|
493
|
+
exit(-1);
|
|
494
|
+
}
|
|
495
|
+
code->function = dlsym(handle,funcname);
|
|
496
|
+
if (code->function == NULL) {
|
|
497
|
+
fprintf(stderr,"Unable to get function: %s\n",code->name);
|
|
498
|
+
exit(-1);
|
|
499
|
+
}
|
|
500
|
+
return codeV;
|
|
501
|
+
}
|
|
502
|
+
#endif
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
|
|
379
506
|
/* Creating a transmit C object. */
|
|
380
507
|
VALUE rcsim_make_transmit(VALUE mod, VALUE left, VALUE right) {
|
|
381
508
|
// printf("rcsim_make_transmit\n");
|
|
@@ -955,6 +1082,30 @@ VALUE rcsim_add_scope_systemIs(VALUE mod, VALUE scopeV, VALUE sysVs) {
|
|
|
955
1082
|
return scopeV;
|
|
956
1083
|
}
|
|
957
1084
|
|
|
1085
|
+
/* Adds codes to a C scope. */
|
|
1086
|
+
VALUE rcsim_add_scope_codes(VALUE mod, VALUE scopeV, VALUE codeVs) {
|
|
1087
|
+
/* Get the C scope from the Ruby value. */
|
|
1088
|
+
Scope scope;
|
|
1089
|
+
value_to_rcsim(ScopeS,scopeV,scope);
|
|
1090
|
+
// printf("rcsim_add_scope_codes with scope=%p\n",scope);
|
|
1091
|
+
/* Prepare the size for the codes. */
|
|
1092
|
+
long num = RARRAY_LEN(codeVs);
|
|
1093
|
+
long old_num = scope->num_codes;
|
|
1094
|
+
scope->num_codes += num;
|
|
1095
|
+
// printf("first scope->codes=%p\n",scope->codes); fflush(stdout);
|
|
1096
|
+
scope->codes = realloc(scope->codes,
|
|
1097
|
+
sizeof(Code[scope->num_codes]));
|
|
1098
|
+
// printf("now scope->codes=%p\n",scope->codes); fflush(stdout);
|
|
1099
|
+
// printf("access test: %p\n",scope->codes[0]); fflush(stdout);
|
|
1100
|
+
/* Get and add the codes from the Ruby value. */
|
|
1101
|
+
for(long i=0; i< num; ++i) {
|
|
1102
|
+
Code code;
|
|
1103
|
+
value_to_rcsim(CodeS,rb_ary_entry(codeVs,i),code);
|
|
1104
|
+
scope->codes[old_num + i] = code;
|
|
1105
|
+
}
|
|
1106
|
+
return scopeV;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
958
1109
|
/* Adds sub scopes to a C scope. */
|
|
959
1110
|
VALUE rcsim_add_scope_scopes(VALUE mod, VALUE scopeV, VALUE scpVs) {
|
|
960
1111
|
/* Get the C scope from the Ruby value. */
|
|
@@ -1051,6 +1202,53 @@ VALUE rcsim_add_behavior_events(VALUE mod, VALUE behaviorV, VALUE eventVs) {
|
|
|
1051
1202
|
return behaviorV;
|
|
1052
1203
|
}
|
|
1053
1204
|
|
|
1205
|
+
|
|
1206
|
+
/* Adds events to a C code. */
|
|
1207
|
+
VALUE rcsim_add_code_events(VALUE mod, VALUE codeV, VALUE eventVs) {
|
|
1208
|
+
/* Get the C code from the Ruby value. */
|
|
1209
|
+
Code code;
|
|
1210
|
+
value_to_rcsim(CodeS,codeV,code);
|
|
1211
|
+
// printf("rcsim_add_codee_events with code=%p\n",code);
|
|
1212
|
+
/* Prepare the size for the events. */
|
|
1213
|
+
long num = RARRAY_LEN(eventVs);
|
|
1214
|
+
long old_num = code->num_events;
|
|
1215
|
+
code->num_events += num;
|
|
1216
|
+
// printf("first code->events=%p\n",code->events); fflush(stdout);
|
|
1217
|
+
code->events = realloc(code->events,
|
|
1218
|
+
sizeof(Event[code->num_events]));
|
|
1219
|
+
// printf("now code->events=%p\n",code->events); fflush(stdout);
|
|
1220
|
+
// printf("access test: %p\n",code->events[0]); fflush(stdout);
|
|
1221
|
+
/* Get and add the events from the Ruby value. */
|
|
1222
|
+
for(long i=0; i< num; ++i) {
|
|
1223
|
+
Event event;
|
|
1224
|
+
value_to_rcsim(EventS,rb_ary_entry(eventVs,i),event);
|
|
1225
|
+
code->events[old_num + i] = event;
|
|
1226
|
+
/* Update the signal of the event to say it activates the code. */
|
|
1227
|
+
SignalI sig = event->signal;
|
|
1228
|
+
switch(event->edge) {
|
|
1229
|
+
case ANYEDGE:
|
|
1230
|
+
sig->num_any++;
|
|
1231
|
+
sig->any = realloc(sig->any,sizeof(Object[sig->num_any]));
|
|
1232
|
+
sig->any[sig->num_any-1] = (Object)code;
|
|
1233
|
+
break;
|
|
1234
|
+
case POSEDGE:
|
|
1235
|
+
sig->num_pos++;
|
|
1236
|
+
sig->pos = realloc(sig->pos,sizeof(Object[sig->num_pos]));
|
|
1237
|
+
sig->pos[sig->num_pos-1] = (Object)code;
|
|
1238
|
+
break;
|
|
1239
|
+
case NEGEDGE:
|
|
1240
|
+
sig->num_neg++;
|
|
1241
|
+
sig->neg = realloc(sig->neg,sizeof(Object[sig->num_neg]));
|
|
1242
|
+
sig->neg[sig->num_neg-1] = (Object)code;
|
|
1243
|
+
break;
|
|
1244
|
+
default:
|
|
1245
|
+
perror("Invalid value for an edge.");
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
return codeV;
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
|
|
1054
1252
|
/* Adds alternate system types to a C system instance. */
|
|
1055
1253
|
VALUE rcsim_add_systemI_systemTs(VALUE mod, VALUE systemIV, VALUE sysVs) {
|
|
1056
1254
|
/* Get the C systemI from the Ruby value. */
|
|
@@ -1381,7 +1579,10 @@ VALUE rcsim_set_behavior_block(VALUE mod, VALUE behaviorV, VALUE blockV) {
|
|
|
1381
1579
|
return behaviorV;
|
|
1382
1580
|
}
|
|
1383
1581
|
|
|
1384
|
-
/** Sets the value for a C signal.
|
|
1582
|
+
/** Sets the value for a C signal.
|
|
1583
|
+
* NOTE: for initialization only (the simulator events are not updated),
|
|
1584
|
+
* otherwise, please use rcsim_transmit_to_signal or
|
|
1585
|
+
* rc_sim_transmit_to_signal_seq. */
|
|
1385
1586
|
VALUE rcsim_set_signal_value(VALUE mod, VALUE signalV, VALUE exprV) {
|
|
1386
1587
|
/* Get the C signal from the Ruby value. */
|
|
1387
1588
|
SignalI signal;
|
|
@@ -1400,6 +1601,127 @@ VALUE rcsim_set_signal_value(VALUE mod, VALUE signalV, VALUE exprV) {
|
|
|
1400
1601
|
return signalV;
|
|
1401
1602
|
}
|
|
1402
1603
|
|
|
1604
|
+
/** Gets the value of a C signal. */
|
|
1605
|
+
VALUE rcsim_get_signal_value(VALUE mod, VALUE signalV) {
|
|
1606
|
+
VALUE res;
|
|
1607
|
+
/* Get the C signal from the Ruby value. */
|
|
1608
|
+
SignalI signal;
|
|
1609
|
+
value_to_rcsim(SignalIS,signalV,signal);
|
|
1610
|
+
// printf("rc_sim_get_signal_value for signal=%s\n",signal->name);
|
|
1611
|
+
/* Returns the current value. */
|
|
1612
|
+
rcsim_to_value(ValueS,signal->c_value,res);
|
|
1613
|
+
return res;
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
/** Transmit a value to a signal in a non-blocking fashion.
|
|
1617
|
+
* NOTE: the simulator events are updated. */
|
|
1618
|
+
VALUE rcsim_transmit_to_signal(VALUE mod, VALUE signalV, VALUE exprV) {
|
|
1619
|
+
/* Get the C signal from the Ruby value. */
|
|
1620
|
+
SignalI signal;
|
|
1621
|
+
value_to_rcsim(SignalIS,signalV,signal);
|
|
1622
|
+
// printf("rc_sim_set_signal_value for signal=%s\n",signal->name);
|
|
1623
|
+
/* Get the C expression from the Ruby value. */
|
|
1624
|
+
Expression expr;
|
|
1625
|
+
value_to_rcsim(ExpressionS,exprV,expr);
|
|
1626
|
+
/* Compute the value from it. */
|
|
1627
|
+
Value value = get_value();
|
|
1628
|
+
value = calc_expression(expr,value);
|
|
1629
|
+
/* Transmit it. */
|
|
1630
|
+
transmit_to_signal(value, signal);
|
|
1631
|
+
/* End, return the transmitted expression. */
|
|
1632
|
+
return exprV;
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
/** Transmit a value to a signal in a blocking fashion.
|
|
1636
|
+
* NOTE: the simulator events are updated. */
|
|
1637
|
+
VALUE rcsim_transmit_to_signal_seq(VALUE mod, VALUE signalV, VALUE exprV) {
|
|
1638
|
+
/* Get the C signal from the Ruby value. */
|
|
1639
|
+
SignalI signal;
|
|
1640
|
+
value_to_rcsim(SignalIS,signalV,signal);
|
|
1641
|
+
// printf("rc_sim_set_signal_value for signal=%s\n",signal->name);
|
|
1642
|
+
/* Get the C expression from the Ruby value. */
|
|
1643
|
+
Expression expr;
|
|
1644
|
+
value_to_rcsim(ExpressionS,exprV,expr);
|
|
1645
|
+
/* Compute the value from it. */
|
|
1646
|
+
Value value = get_value();
|
|
1647
|
+
value = calc_expression(expr,value);
|
|
1648
|
+
/* Transmit it. */
|
|
1649
|
+
transmit_to_signal_seq(value, signal);
|
|
1650
|
+
/* End, return the transmitted expression. */
|
|
1651
|
+
return exprV;
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
|
|
1655
|
+
|
|
1656
|
+
|
|
1657
|
+
/** Gets the value of a C signal as a Ruby fixnum.
|
|
1658
|
+
* Sets 0 if the value contains x or z bits. */
|
|
1659
|
+
VALUE rcsim_get_signal_fixnum(VALUE mod, VALUE signalV) {
|
|
1660
|
+
Value value;
|
|
1661
|
+
/* Get the C signal from the Ruby value. */
|
|
1662
|
+
SignalI signal;
|
|
1663
|
+
value_to_rcsim(SignalIS,signalV,signal);
|
|
1664
|
+
// printf("rc_sim_get_signal_fixnum for signal=%s\n",signal->name);
|
|
1665
|
+
/* Get the value from the signal. */
|
|
1666
|
+
value = signal->c_value;
|
|
1667
|
+
// /* Is the value a numeric? */
|
|
1668
|
+
// if(value->numeric == 1) {
|
|
1669
|
+
// /* Yes, return it as a Ruby fixnum. */
|
|
1670
|
+
// return LONG2FIX(value->data_int);
|
|
1671
|
+
// } else {
|
|
1672
|
+
// /* No, return 0. */
|
|
1673
|
+
// return LONG2FIX(0);
|
|
1674
|
+
// }
|
|
1675
|
+
return LONG2FIX(value2integer(value));
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
/** Transmit a Ruby fixnum to a signal in a non-blocking fashion.
|
|
1679
|
+
* NOTE: the simulator events are updated. */
|
|
1680
|
+
VALUE rcsim_transmit_fixnum_to_signal(VALUE mod, VALUE signalV, VALUE valR) {
|
|
1681
|
+
/* Get the C signal from the Ruby value. */
|
|
1682
|
+
SignalI signal;
|
|
1683
|
+
value_to_rcsim(SignalIS,signalV,signal);
|
|
1684
|
+
/* Compute the simualtion value from valR. */
|
|
1685
|
+
Value value = get_value();
|
|
1686
|
+
value->type = signal->type;
|
|
1687
|
+
value->numeric = 1;
|
|
1688
|
+
value->data_int = FIX2LONG(valR);
|
|
1689
|
+
/* Transmit it. */
|
|
1690
|
+
transmit_to_signal(value, signal);
|
|
1691
|
+
/* End, return the transmitted expression. */
|
|
1692
|
+
return valR;
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
/** Transmit a Ruby fixnum to a signal in a non-blocking fashion.
|
|
1696
|
+
* NOTE: the simulator events are updated. */
|
|
1697
|
+
VALUE rcsim_transmit_fixnum_to_signal_seq(VALUE mod, VALUE signalV, VALUE valR) {
|
|
1698
|
+
/* Get the C signal from the Ruby value. */
|
|
1699
|
+
SignalI signal;
|
|
1700
|
+
value_to_rcsim(SignalIS,signalV,signal);
|
|
1701
|
+
/* Compute the simualtion value from valR. */
|
|
1702
|
+
Value value = get_value();
|
|
1703
|
+
value->type = signal->type;
|
|
1704
|
+
value->numeric = 1;
|
|
1705
|
+
value->data_int = FIX2LONG(valR);
|
|
1706
|
+
/* Transmit it. */
|
|
1707
|
+
transmit_to_signal_seq(value, signal);
|
|
1708
|
+
/* End, return the transmitted expression. */
|
|
1709
|
+
return valR;
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1712
|
+
|
|
1713
|
+
// /** Execute a behavior. */
|
|
1714
|
+
// VALUE rcsim_execute_behavior(VALUE mod, VALUE behaviorV) {
|
|
1715
|
+
// /* Get the behavior. */
|
|
1716
|
+
// Behavior behavior;
|
|
1717
|
+
// value_to_rcsim(BehaviorS,behaviorV,behavior);
|
|
1718
|
+
// /* Execute the behavior. */
|
|
1719
|
+
// execute_statement((Statement)(behavior->block),0,behavior);
|
|
1720
|
+
// /* Returns the behavior. */
|
|
1721
|
+
// return behaviorV;
|
|
1722
|
+
// }
|
|
1723
|
+
|
|
1724
|
+
|
|
1403
1725
|
|
|
1404
1726
|
/** Starts the C-Ruby hybrid simulation.
|
|
1405
1727
|
* @param systemTV the top system type.
|
|
@@ -1432,6 +1754,67 @@ VALUE rcsim_main(VALUE mod, VALUE systemTV, VALUE name, VALUE outmodeV) {
|
|
|
1432
1754
|
}
|
|
1433
1755
|
|
|
1434
1756
|
|
|
1757
|
+
/** The wrapper for calling Ruby functions from the simulator. */
|
|
1758
|
+
void ruby_function_wrap(Code code) {
|
|
1759
|
+
/* Convert the C code object to a Ruby VALUE. */
|
|
1760
|
+
VALUE codeR;
|
|
1761
|
+
rcsim_to_value(CodeS,code,codeR);
|
|
1762
|
+
/* Call the ruby function launcher. */
|
|
1763
|
+
rb_funcall(rb_cObject,rb_intern(code->name),0,Qnil);
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
|
|
1767
|
+
/** The C interface. */
|
|
1768
|
+
|
|
1769
|
+
#if defined(_WIN32) || defined(_WIN64)
|
|
1770
|
+
__declspec(dllexport) SignalI c_get_port(char* name);
|
|
1771
|
+
__declspec(dllexport) unsigned long long c_read_port(SignalI port);
|
|
1772
|
+
__declspec(dllexport) unsigned long long c_write_port(SignalI port, unsigned long long val);
|
|
1773
|
+
#endif
|
|
1774
|
+
|
|
1775
|
+
|
|
1776
|
+
/** The wrapper for getting an interface port for C software. */
|
|
1777
|
+
SignalI c_get_port(char* name) {
|
|
1778
|
+
/* Get the C signal as a value. */
|
|
1779
|
+
VALUE sigV = rb_hash_aref(RCSimCports,ID2SYM(rb_intern(name)));
|
|
1780
|
+
/* Was there a signal? */
|
|
1781
|
+
if (!NIL_P(sigV)) {
|
|
1782
|
+
/* Yes, return it. */
|
|
1783
|
+
SignalI sig;
|
|
1784
|
+
value_to_rcsim(SignalIS,sigV,sig);
|
|
1785
|
+
return sig;
|
|
1786
|
+
} else {
|
|
1787
|
+
/* No return NULL. */
|
|
1788
|
+
return NULL;
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
/** The wrapper for getting a value from a port. */
|
|
1793
|
+
unsigned long long c_read_port(SignalI port) {
|
|
1794
|
+
Value val = port->c_value;
|
|
1795
|
+
if (val->numeric == 1) {
|
|
1796
|
+
/* There is a defined value, return it. */
|
|
1797
|
+
return val->data_int;
|
|
1798
|
+
} else {
|
|
1799
|
+
/* The value is undefined, return 0. */
|
|
1800
|
+
return 0;
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
/** The wrapper for setting a value to a port. */
|
|
1805
|
+
unsigned long long c_write_port(SignalI port, unsigned long long val) {
|
|
1806
|
+
/* Generate the value. */
|
|
1807
|
+
Value value = get_value();
|
|
1808
|
+
value->numeric = 1;
|
|
1809
|
+
value->data_int = val;
|
|
1810
|
+
/* Transmit it. */
|
|
1811
|
+
transmit_to_signal_seq(value, port);
|
|
1812
|
+
/* Returns the transmitted value. */
|
|
1813
|
+
return val;
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
|
|
1817
|
+
/* The simulator creation. */
|
|
1435
1818
|
|
|
1436
1819
|
|
|
1437
1820
|
/** The initialization of the C-part of the C-Ruby hybrid HDLRuby simulator. */
|
|
@@ -1440,9 +1823,17 @@ void Init_hruby_sim() {
|
|
|
1440
1823
|
make_sym_IDs();
|
|
1441
1824
|
/* Create the module for C-Ruby interface. */
|
|
1442
1825
|
VALUE mod = rb_define_module("RCSimCinterface");
|
|
1826
|
+
RCSimCinterface = mod;
|
|
1827
|
+
|
|
1828
|
+
/* Create the table of C ports and add it to the C-Ruby interface. */
|
|
1829
|
+
RCSimCports = rb_hash_new();
|
|
1830
|
+
rb_define_const(mod,"CPorts",RCSimCports);
|
|
1831
|
+
|
|
1443
1832
|
|
|
1444
1833
|
/* Create the class that wraps C pointers. */
|
|
1445
1834
|
RCSimPointer = rb_define_class("RCSimPointer",rb_cObject);
|
|
1835
|
+
/* No allocator for C pointers. */
|
|
1836
|
+
rb_undef_alloc_func(RCSimPointer);
|
|
1446
1837
|
|
|
1447
1838
|
/* Add the interface methods. */
|
|
1448
1839
|
/* Getting the C simulation type objects. */
|
|
@@ -1456,6 +1847,8 @@ void Init_hruby_sim() {
|
|
|
1456
1847
|
rb_define_singleton_method(mod,"rcsim_make_event",rcsim_make_event,2);
|
|
1457
1848
|
rb_define_singleton_method(mod,"rcsim_make_signal",rcsim_make_signal,2);
|
|
1458
1849
|
rb_define_singleton_method(mod,"rcsim_make_systemI",rcsim_make_systemI,2);
|
|
1850
|
+
rb_define_singleton_method(mod,"rcsim_make_code",rcsim_make_code,2);
|
|
1851
|
+
rb_define_singleton_method(mod,"rcsim_load_c",rcsim_load_c,3);
|
|
1459
1852
|
rb_define_singleton_method(mod,"rcsim_make_transmit",rcsim_make_transmit,2);
|
|
1460
1853
|
rb_define_singleton_method(mod,"rcsim_make_print",rcsim_make_print,0);
|
|
1461
1854
|
rb_define_singleton_method(mod,"rcsim_make_timeWait",rcsim_make_timeWait,2);
|
|
@@ -1482,8 +1875,10 @@ void Init_hruby_sim() {
|
|
|
1482
1875
|
rb_define_singleton_method(mod,"rcsim_add_scope_inners",rcsim_add_scope_inners,2);
|
|
1483
1876
|
rb_define_singleton_method(mod,"rcsim_add_scope_behaviors",rcsim_add_scope_behaviors,2);
|
|
1484
1877
|
rb_define_singleton_method(mod,"rcsim_add_scope_systemIs",rcsim_add_scope_systemIs,2);
|
|
1878
|
+
rb_define_singleton_method(mod,"rcsim_add_scope_codes",rcsim_add_scope_codes,2);
|
|
1485
1879
|
rb_define_singleton_method(mod,"rcsim_add_scope_scopes",rcsim_add_scope_scopes,2);
|
|
1486
1880
|
rb_define_singleton_method(mod,"rcsim_add_behavior_events",rcsim_add_behavior_events,2);
|
|
1881
|
+
rb_define_singleton_method(mod,"rcsim_add_code_events",rcsim_add_code_events,2);
|
|
1487
1882
|
rb_define_singleton_method(mod,"rcsim_add_systemI_systemTs",rcsim_add_systemI_systemTs,2);
|
|
1488
1883
|
rb_define_singleton_method(mod,"rcsim_add_signal_signals",rcsim_add_signal_signals,2);
|
|
1489
1884
|
rb_define_singleton_method(mod,"rcsim_add_print_args",rcsim_add_print_args,2);
|
|
@@ -1501,6 +1896,10 @@ void Init_hruby_sim() {
|
|
|
1501
1896
|
rb_define_singleton_method(mod,"rcsim_set_signal_value",rcsim_set_signal_value,2);
|
|
1502
1897
|
/* Starting the simulation. */
|
|
1503
1898
|
rb_define_singleton_method(mod,"rcsim_main",rcsim_main,3);
|
|
1899
|
+
/* The Ruby software interface. */
|
|
1900
|
+
rb_define_singleton_method(mod,"rcsim_get_signal_fixnum",rcsim_get_signal_fixnum,1);
|
|
1901
|
+
rb_define_singleton_method(mod,"rcsim_transmit_fixnum_to_signal_seq",rcsim_transmit_fixnum_to_signal_seq,2);
|
|
1902
|
+
// rb_define_singleton_method(mod,"rcsim_execute_behavior",rcsim_execute_behavior,1);
|
|
1504
1903
|
|
|
1505
1904
|
}
|
|
1506
1905
|
|
data/ext/hruby_sim/hruby_sim.h
CHANGED
|
@@ -605,9 +605,10 @@ typedef struct CodeS_ {
|
|
|
605
605
|
Kind kind; /* The kind of object. */
|
|
606
606
|
Object owner; /* The owner if any. */
|
|
607
607
|
|
|
608
|
+
char* name; /* The name of the called function. */
|
|
608
609
|
int num_events; /* The number of events. */
|
|
609
610
|
Event* events; /* The events of the behavior. */
|
|
610
|
-
void (*function)(); /* The function to execute for the code. */
|
|
611
|
+
void (*function)(Code); /* The function to execute for the code. */
|
|
611
612
|
|
|
612
613
|
int enabled; /* Tells if the behavior is enabled or not. */
|
|
613
614
|
|
|
@@ -50,6 +50,12 @@
|
|
|
50
50
|
// ({ __typeof__ (v) _v = (v); \
|
|
51
51
|
// _v->type->flags.sign ? (_v->data[_v->size-1] >> (INT_BIT-1)) ? UINT_MAX : 0 : 0; })
|
|
52
52
|
|
|
53
|
+
/** Fix the sign of a numeric value. */
|
|
54
|
+
#define fix_numeric_sign(v) \
|
|
55
|
+
({if ((v)->type->flags.sign && (type_width((v)->type) < 64) && ((v)->data_int & (1ULL << (type_width((v)->type)-1)))) {\
|
|
56
|
+
(v)->data_int |= (-1LL) << type_width((v)->type);\
|
|
57
|
+
}})
|
|
58
|
+
|
|
53
59
|
/* The type engine: each type is simplified to a vector of X elements
|
|
54
60
|
* of Y bits. */
|
|
55
61
|
|
|
@@ -231,7 +237,7 @@ Value make_value(Type type, int numeric) {
|
|
|
231
237
|
/** Make the size of a value able to store size ints.
|
|
232
238
|
* @note The content of the value is lost!
|
|
233
239
|
* @note do not change the type of the value, only its capacity.
|
|
234
|
-
* @
|
|
240
|
+
* @param value the value to change
|
|
235
241
|
* @param size the size to match */
|
|
236
242
|
void resize_value(Value value, unsigned long long size) {
|
|
237
243
|
if (value->capacity < size) {
|
|
@@ -900,6 +906,7 @@ static Value greater_equal_value_defined_bitstring(Value src0, Value src1, Value
|
|
|
900
906
|
/* Converts the values to integers. */
|
|
901
907
|
unsigned long long src0i = value2integer(src0);
|
|
902
908
|
unsigned long long src1i = value2integer(src1);
|
|
909
|
+
// printf("src0i=%lld src1i=%lld, src0i.sign=%d src0i.width=%d, src1i.sign=%d src1i.width=%d\n",src0i,src1i,src0->type->flags.sign,type_width(src0->type),src1->type->flags.sign,type_width(src1->type));
|
|
903
910
|
/* Perform the comparison. */
|
|
904
911
|
if (src0->type->flags.sign) {
|
|
905
912
|
if (src1->type->flags.sign)
|
|
@@ -1275,7 +1282,7 @@ static Value shift_left_value_bitstring_numeric(Value src0, Value src1, Value ds
|
|
|
1275
1282
|
char d0 = src0_data[count];
|
|
1276
1283
|
/* Set it to the destination at the right place. */
|
|
1277
1284
|
unsigned long long pos = count + sh;
|
|
1278
|
-
if ((pos
|
|
1285
|
+
if ((pos>=0) && (pos<width0)) {
|
|
1279
1286
|
dst_data[pos] = d0;
|
|
1280
1287
|
}
|
|
1281
1288
|
}
|
|
@@ -1290,6 +1297,7 @@ static Value shift_left_value_bitstring_numeric(Value src0, Value src1, Value ds
|
|
|
1290
1297
|
* @param dst the destination
|
|
1291
1298
|
* @return dst */
|
|
1292
1299
|
static Value shift_right_value_bitstring_numeric(Value src0, Value src1, Value dst) {
|
|
1300
|
+
// printf("shift_right_value_bitstring_numeric with src0=%s src1=%lld\n",src0->data_str,src1->data_int);
|
|
1293
1301
|
unsigned long long count;
|
|
1294
1302
|
/* Get the widths of the first source. */
|
|
1295
1303
|
unsigned long long width0 = type_width(src0->type);
|
|
@@ -1319,10 +1327,11 @@ static Value shift_right_value_bitstring_numeric(Value src0, Value src1, Value d
|
|
|
1319
1327
|
char d0 = src0_data[count];
|
|
1320
1328
|
/* Set it to the destination at the right place. */
|
|
1321
1329
|
unsigned long long pos = count + sh;
|
|
1322
|
-
if ((pos
|
|
1330
|
+
if ((pos>=0) && (pos<width0)) {
|
|
1323
1331
|
dst_data[pos] = d0;
|
|
1324
1332
|
}
|
|
1325
1333
|
}
|
|
1334
|
+
// printf("result=%s\n",dst_data);
|
|
1326
1335
|
/* Return the destination value. */
|
|
1327
1336
|
return dst;
|
|
1328
1337
|
}
|
|
@@ -1683,6 +1692,7 @@ Value read_range_bitstring(Value src,
|
|
|
1683
1692
|
unsigned long long first, unsigned long long last,
|
|
1684
1693
|
Type base, Value dst) {
|
|
1685
1694
|
// printf("read_range_bitstring with first=%lld last=%lld src=%s\n",first,last,src->data_str);
|
|
1695
|
+
// printf("read_range_bitstring with first=%lld last=%lld\n",first,last);
|
|
1686
1696
|
/* Ensure first is the smaller. */
|
|
1687
1697
|
if (first > last) {
|
|
1688
1698
|
long long tmp = last;
|
|
@@ -1705,6 +1715,7 @@ Value read_range_bitstring(Value src,
|
|
|
1705
1715
|
|
|
1706
1716
|
/* Performs the read. */
|
|
1707
1717
|
memcpy(dst->data_str,src->data_str + first, length);
|
|
1718
|
+
// printf("result: %s\n",dst->data_str);
|
|
1708
1719
|
|
|
1709
1720
|
/* Return the destination. */
|
|
1710
1721
|
return dst;
|
|
@@ -1888,9 +1899,15 @@ static Value mul_value_numeric(Value src0, Value src1, Value dst) {
|
|
|
1888
1899
|
/* Sets state of the destination using the first source. */
|
|
1889
1900
|
dst->type = src0->type;
|
|
1890
1901
|
dst->numeric = 1;
|
|
1902
|
+
/* Fix the numeric signs since multiply is sensitive to it. */
|
|
1903
|
+
// printf("src0 type_width=%d src1 type_width=%d (%d)\n",type_width(src0->type),type_width(src1->type),src1->type->flags.sign);
|
|
1904
|
+
fix_numeric_sign(src0);
|
|
1905
|
+
fix_numeric_sign(src1);
|
|
1906
|
+
// printf("Then src0->data_int=%llx src1->data_int=%llx\n",src0->data_int,src1->data_int);
|
|
1891
1907
|
|
|
1892
1908
|
/* Perform the multiplication. */
|
|
1893
1909
|
dst->data_int = fix_numeric_type(dst->type, src0->data_int * src1->data_int);
|
|
1910
|
+
// printf("result=%llx\n",dst->data_int);
|
|
1894
1911
|
return dst;
|
|
1895
1912
|
}
|
|
1896
1913
|
|
|
@@ -1905,6 +1922,10 @@ static Value div_value_numeric(Value src0, Value src1, Value dst) {
|
|
|
1905
1922
|
dst->type = src0->type;
|
|
1906
1923
|
dst->numeric = 1;
|
|
1907
1924
|
|
|
1925
|
+
/* Fix the numeric signs since multiply is sensitive to it. */
|
|
1926
|
+
fix_numeric_sign(src0);
|
|
1927
|
+
fix_numeric_sign(src1);
|
|
1928
|
+
|
|
1908
1929
|
/* Perform the division. */
|
|
1909
1930
|
dst->data_int = fix_numeric_type(dst->type, src0->data_int / src1->data_int);
|
|
1910
1931
|
return dst;
|
|
@@ -3347,13 +3368,20 @@ RefRangeS make_ref_rangeS(SignalI signal, Type typ,
|
|
|
3347
3368
|
* @param value the value to convert
|
|
3348
3369
|
* @return the resulting int. */
|
|
3349
3370
|
unsigned long long value2integer(Value value) {
|
|
3371
|
+
// printf("value2integer\n");
|
|
3350
3372
|
unsigned long long width = type_width(value->type);
|
|
3351
|
-
/* If the value is numeric,
|
|
3373
|
+
/* If the value is numeric, return it with its sign propoerly extended*/
|
|
3352
3374
|
if (value->numeric) {
|
|
3353
3375
|
// printf("width=%llu\n",width);
|
|
3354
3376
|
if (width == 64)
|
|
3377
|
+
/* Nothing to do. */
|
|
3355
3378
|
return value->data_int;
|
|
3379
|
+
else if (value->type->flags.sign &&
|
|
3380
|
+
((value->data_int >> (width-1))&1))
|
|
3381
|
+
/* Sign extension. */
|
|
3382
|
+
return value->data_int | (0xFFFFFFFFFFFFFFFFULL << width);
|
|
3356
3383
|
else
|
|
3384
|
+
/* Zero extension. */
|
|
3357
3385
|
return value->data_int & ~(0xFFFFFFFFFFFFFFFFULL << width);
|
|
3358
3386
|
}
|
|
3359
3387
|
/* Otherwise convert the bitstring to an integer if possible,
|
|
@@ -3377,11 +3405,10 @@ unsigned long long value2integer(Value value) {
|
|
|
3377
3405
|
res = (res << 1) | bit;
|
|
3378
3406
|
}
|
|
3379
3407
|
// printf("first res=%llx\n",res);
|
|
3380
|
-
unsigned long long bit0 = (data_str[width-1]-'0') << i;
|
|
3381
3408
|
/* Perform the sign extension if required. */
|
|
3382
|
-
if (
|
|
3409
|
+
if (value->type->flags.sign) {
|
|
3410
|
+
unsigned long long bit0 = (data_str[width-1]-'0') << i;
|
|
3383
3411
|
for(; i<LONG_LONG_BIT; ++i) {
|
|
3384
|
-
// res = (res << 1) | bit;
|
|
3385
3412
|
res |= bit0;
|
|
3386
3413
|
bit0 <<= 1;
|
|
3387
3414
|
}
|
|
@@ -331,7 +331,8 @@ void hruby_sim_update_signals() {
|
|
|
331
331
|
/* Is the code really activated? */
|
|
332
332
|
if (cod->enabled && cod->activated) {
|
|
333
333
|
/* Yes, execute it. */
|
|
334
|
-
cod->function();
|
|
334
|
+
// cod->function();
|
|
335
|
+
cod->function(cod); // NOTE: cod argument is required for identification.
|
|
335
336
|
/* And deactivate it. */
|
|
336
337
|
cod->activated = 0;
|
|
337
338
|
}
|
|
@@ -368,15 +369,24 @@ void hruby_sim_advance_time() {
|
|
|
368
369
|
* @param status the enable status. */
|
|
369
370
|
static void set_enable_scope(Scope scope, int status) {
|
|
370
371
|
int i;
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
372
|
+
|
|
373
|
+
int num_beh = scope->num_behaviors;
|
|
374
|
+
Behavior* behs = scope->behaviors;
|
|
375
|
+
|
|
376
|
+
int num_cod = scope->num_codes;
|
|
377
|
+
Code* cods = scope->codes;
|
|
378
|
+
|
|
379
|
+
int num_scp = scope->num_scopes;
|
|
380
|
+
Scope* scps = scope->scopes;
|
|
375
381
|
|
|
376
382
|
/* Enable the behaviors. */
|
|
377
383
|
for(i=0; i<num_beh; ++i) {
|
|
378
384
|
behs[i]->enabled = status;
|
|
379
385
|
}
|
|
386
|
+
/* Enable the codes. */
|
|
387
|
+
for(i=0; i<num_cod; ++i) {
|
|
388
|
+
cods[i]->enabled = status;
|
|
389
|
+
}
|
|
380
390
|
|
|
381
391
|
/* Recurse on the sub scopes. */
|
|
382
392
|
for(i=0; i<num_scp; ++i) {
|