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.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/HDLRuby.gemspec +1 -0
  3. data/README.html +2330 -2670
  4. data/README.md +400 -100
  5. data/ext/hruby_sim/hruby_rcsim_build.c +402 -3
  6. data/ext/hruby_sim/hruby_sim.h +2 -1
  7. data/ext/hruby_sim/hruby_sim_calc.c +34 -7
  8. data/ext/hruby_sim/hruby_sim_core.c +15 -5
  9. data/ext/hruby_sim/hruby_sim_tree_calc.c +112 -23
  10. data/lib/HDLRuby/hdr_samples/c_program/echo.c +33 -0
  11. data/lib/HDLRuby/hdr_samples/comparison_bench.rb +2 -2
  12. data/lib/HDLRuby/hdr_samples/counter_bench.rb +1 -1
  13. data/lib/HDLRuby/hdr_samples/counter_dff_bench.rb +8 -7
  14. data/lib/HDLRuby/hdr_samples/dff_properties.rb +2 -0
  15. data/lib/HDLRuby/hdr_samples/enum_as_param.rb +52 -0
  16. data/lib/HDLRuby/hdr_samples/linear_test.rb +2 -0
  17. data/lib/HDLRuby/hdr_samples/logic_bench.rb +6 -0
  18. data/lib/HDLRuby/hdr_samples/mei8.rb +6 -6
  19. data/lib/HDLRuby/hdr_samples/mei8_bench.rb +6 -6
  20. data/lib/HDLRuby/hdr_samples/memory_test.rb +2 -0
  21. data/lib/HDLRuby/hdr_samples/named_sub.rb +9 -5
  22. data/lib/HDLRuby/hdr_samples/ram.rb +7 -6
  23. data/lib/HDLRuby/hdr_samples/ruby_fir_hw.rb +2 -0
  24. data/lib/HDLRuby/hdr_samples/ruby_program/echo.rb +9 -0
  25. data/lib/HDLRuby/hdr_samples/ruby_program/stdrw.rb +6 -0
  26. data/lib/HDLRuby/hdr_samples/ruby_program/sw_cpu_terminal.rb +614 -0
  27. data/lib/HDLRuby/hdr_samples/ruby_program/sw_inc_mem.rb +32 -0
  28. data/lib/HDLRuby/hdr_samples/ruby_program/sw_log.rb +33 -0
  29. data/lib/HDLRuby/hdr_samples/struct.rb +15 -3
  30. data/lib/HDLRuby/hdr_samples/with_board.rb +63 -0
  31. data/lib/HDLRuby/hdr_samples/with_bram.rb +1 -1
  32. data/lib/HDLRuby/hdr_samples/with_bram_frame_stack.rb +1 -1
  33. data/lib/HDLRuby/hdr_samples/with_bram_stack.rb +1 -1
  34. data/lib/HDLRuby/hdr_samples/with_channel.rb +2 -0
  35. data/lib/HDLRuby/hdr_samples/with_channel_other.rb +2 -0
  36. data/lib/HDLRuby/hdr_samples/with_class.rb +3 -1
  37. data/lib/HDLRuby/hdr_samples/with_clocks.rb +42 -0
  38. data/lib/HDLRuby/hdr_samples/with_connector.rb +2 -0
  39. data/lib/HDLRuby/hdr_samples/with_connector_memory.rb +2 -0
  40. data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +6 -0
  41. data/lib/HDLRuby/hdr_samples/with_fixpoint_adv.rb +73 -0
  42. data/lib/HDLRuby/hdr_samples/with_leftright.rb +1 -1
  43. data/lib/HDLRuby/hdr_samples/with_of.rb +1 -1
  44. data/lib/HDLRuby/hdr_samples/with_program_c.rb +28 -0
  45. data/lib/HDLRuby/hdr_samples/with_program_ruby.rb +28 -0
  46. data/lib/HDLRuby/hdr_samples/with_program_ruby_cpu.rb +234 -0
  47. data/lib/HDLRuby/hdr_samples/with_program_ruby_io.rb +23 -0
  48. data/lib/HDLRuby/hdr_samples/with_program_ruby_mem.rb +58 -0
  49. data/lib/HDLRuby/hdr_samples/with_program_ruby_threads.rb +56 -0
  50. data/lib/HDLRuby/hdr_samples/with_sequencer.rb +17 -0
  51. data/lib/HDLRuby/hdr_samples/with_sequencer_channel.rb +58 -0
  52. data/lib/HDLRuby/hdr_samples/with_sequencer_enumerable.rb +10 -0
  53. data/lib/HDLRuby/hdr_samples/with_sequencer_enumerator.rb +18 -4
  54. data/lib/HDLRuby/hdr_samples/with_sequencer_func.rb +2 -4
  55. data/lib/HDLRuby/hdr_samples/with_sequencer_sync.rb +2 -1
  56. data/lib/HDLRuby/hdrcc.rb +72 -21
  57. data/lib/HDLRuby/hruby_error.rb +13 -0
  58. data/lib/HDLRuby/hruby_high.rb +125 -26
  59. data/lib/HDLRuby/hruby_low.rb +171 -3
  60. data/lib/HDLRuby/hruby_low2programs.rb +47 -0
  61. data/lib/HDLRuby/hruby_low_resolve.rb +3 -2
  62. data/lib/HDLRuby/hruby_low_without_namespace.rb +133 -5
  63. data/lib/HDLRuby/hruby_low_without_subsignals.rb +1 -1
  64. data/lib/HDLRuby/hruby_rcsim.rb +113 -6
  65. data/lib/HDLRuby/hruby_serializer.rb +2 -1
  66. data/lib/HDLRuby/hruby_verilog.rb +94 -20
  67. data/lib/HDLRuby/hruby_verilog_name.rb +3 -17
  68. data/lib/HDLRuby/std/clocks.rb +118 -50
  69. data/lib/HDLRuby/std/fixpoint.rb +2 -2
  70. data/lib/HDLRuby/std/function_generator.rb +1 -1
  71. data/lib/HDLRuby/std/linear.rb +7 -7
  72. data/lib/HDLRuby/std/sequencer.rb +263 -13
  73. data/lib/HDLRuby/std/sequencer_channel.rb +90 -0
  74. data/lib/HDLRuby/std/sequencer_func.rb +28 -15
  75. data/lib/HDLRuby/std/std.rb +6 -0
  76. data/lib/HDLRuby/ui/hruby_board.rb +1079 -0
  77. data/lib/HDLRuby/version.rb +1 -1
  78. data/lib/c/Rakefile +8 -0
  79. data/lib/c/cHDL.h +12 -0
  80. data/lib/c/extconf.rb +7 -0
  81. data/lib/rubyHDL.rb +33 -0
  82. data/tuto/gui_accum.png +0 -0
  83. data/tuto/gui_board.png +0 -0
  84. data/tuto/tutorial_sw.html +2263 -1890
  85. data/tuto/tutorial_sw.md +957 -62
  86. metadata +43 -5
  87. data/README.pdf +0 -0
  88. 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
 
@@ -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
- * @praam value the value to change
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>0) && (pos<width0)) {
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>0) && (pos<width0)) {
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, just return its data as is. */
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 (i>=width && value->type->flags.sign) {
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
- int num_beh = scope->num_behaviors;
372
- Behavior* behs = scope->behaviors;
373
- int num_scp = scope->num_scopes;
374
- Scope* scps = scope->scopes;
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) {