HDLRuby 3.2.0 → 3.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.html +4411 -2930
- data/README.md +396 -102
- data/ext/hruby_sim/hruby_rcsim_build.c +400 -3
- data/ext/hruby_sim/hruby_sim.h +2 -1
- data/ext/hruby_sim/hruby_sim_calc.c +1 -1
- data/ext/hruby_sim/hruby_sim_core.c +15 -5
- data/ext/hruby_sim/hruby_sim_tree_calc.c +1 -1
- data/lib/HDLRuby/hdr_samples/c_program/echo.c +33 -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/with_board.rb +63 -0
- data/lib/HDLRuby/hdr_samples/with_clocks.rb +42 -0
- 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_func.rb +2 -4
- data/lib/HDLRuby/hdrcc.rb +60 -21
- data/lib/HDLRuby/hruby_error.rb +13 -0
- data/lib/HDLRuby/hruby_high.rb +50 -7
- data/lib/HDLRuby/hruby_low.rb +74 -30
- data/lib/HDLRuby/hruby_rcsim.rb +89 -5
- data/lib/HDLRuby/std/clocks.rb +118 -50
- data/lib/HDLRuby/std/std.rb +5 -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 +4163 -2081
- data/tuto/tutorial_sw.md +957 -62
- metadata +24 -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,6 +1823,12 @@ 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);
|
@@ -1458,6 +1847,8 @@ void Init_hruby_sim() {
|
|
1458
1847
|
rb_define_singleton_method(mod,"rcsim_make_event",rcsim_make_event,2);
|
1459
1848
|
rb_define_singleton_method(mod,"rcsim_make_signal",rcsim_make_signal,2);
|
1460
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);
|
1461
1852
|
rb_define_singleton_method(mod,"rcsim_make_transmit",rcsim_make_transmit,2);
|
1462
1853
|
rb_define_singleton_method(mod,"rcsim_make_print",rcsim_make_print,0);
|
1463
1854
|
rb_define_singleton_method(mod,"rcsim_make_timeWait",rcsim_make_timeWait,2);
|
@@ -1484,8 +1875,10 @@ void Init_hruby_sim() {
|
|
1484
1875
|
rb_define_singleton_method(mod,"rcsim_add_scope_inners",rcsim_add_scope_inners,2);
|
1485
1876
|
rb_define_singleton_method(mod,"rcsim_add_scope_behaviors",rcsim_add_scope_behaviors,2);
|
1486
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);
|
1487
1879
|
rb_define_singleton_method(mod,"rcsim_add_scope_scopes",rcsim_add_scope_scopes,2);
|
1488
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);
|
1489
1882
|
rb_define_singleton_method(mod,"rcsim_add_systemI_systemTs",rcsim_add_systemI_systemTs,2);
|
1490
1883
|
rb_define_singleton_method(mod,"rcsim_add_signal_signals",rcsim_add_signal_signals,2);
|
1491
1884
|
rb_define_singleton_method(mod,"rcsim_add_print_args",rcsim_add_print_args,2);
|
@@ -1503,6 +1896,10 @@ void Init_hruby_sim() {
|
|
1503
1896
|
rb_define_singleton_method(mod,"rcsim_set_signal_value",rcsim_set_signal_value,2);
|
1504
1897
|
/* Starting the simulation. */
|
1505
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);
|
1506
1903
|
|
1507
1904
|
}
|
1508
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
|
|
@@ -237,7 +237,7 @@ Value make_value(Type type, int numeric) {
|
|
237
237
|
/** Make the size of a value able to store size ints.
|
238
238
|
* @note The content of the value is lost!
|
239
239
|
* @note do not change the type of the value, only its capacity.
|
240
|
-
* @
|
240
|
+
* @param value the value to change
|
241
241
|
* @param size the size to match */
|
242
242
|
void resize_value(Value value, unsigned long long size) {
|
243
243
|
if (value->capacity < size) {
|
@@ -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) {
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include "cHDL.h"
|
3
|
+
|
4
|
+
#if defined(_WIN32) || defined(_WIN64)
|
5
|
+
__declspec(dllexport)
|
6
|
+
#endif
|
7
|
+
void echo(void* code) {
|
8
|
+
static void* inP = NULL;
|
9
|
+
static void* outP = NULL;
|
10
|
+
unsigned long long data;
|
11
|
+
|
12
|
+
/* Is the input port obtained? */
|
13
|
+
if (inP == NULL) {
|
14
|
+
/* No, get it. */
|
15
|
+
inP = c_get_port("inP");
|
16
|
+
}
|
17
|
+
|
18
|
+
/* Is the input port obtained? */
|
19
|
+
if (outP == NULL) {
|
20
|
+
/* No, get it. */
|
21
|
+
outP = c_get_port("outP");
|
22
|
+
}
|
23
|
+
|
24
|
+
/* Get data from the input port. */
|
25
|
+
data = c_read_port(inP);
|
26
|
+
|
27
|
+
/* Display it. */
|
28
|
+
printf("Echoing: %llu\n", data);
|
29
|
+
|
30
|
+
/* Echoing the data. */
|
31
|
+
c_write_port(outP,data);
|
32
|
+
|
33
|
+
}
|