HDLRuby 2.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (224) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +4 -0
  6. data/HDLRuby.gemspec +36 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +2774 -0
  9. data/README.pdf +0 -0
  10. data/Rakefile +10 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/exe/hdrcc +3 -0
  14. data/lib/HDLRuby/alcc.rb +137 -0
  15. data/lib/HDLRuby/backend/hruby_allocator.rb +69 -0
  16. data/lib/HDLRuby/backend/hruby_c_allocator.rb +76 -0
  17. data/lib/HDLRuby/hdr_samples/adder.rb +7 -0
  18. data/lib/HDLRuby/hdr_samples/adder_assign_error.rb +11 -0
  19. data/lib/HDLRuby/hdr_samples/adder_bench.rb +27 -0
  20. data/lib/HDLRuby/hdr_samples/adder_gen.rb +7 -0
  21. data/lib/HDLRuby/hdr_samples/adder_nodef_error.rb +7 -0
  22. data/lib/HDLRuby/hdr_samples/addsub.rb +19 -0
  23. data/lib/HDLRuby/hdr_samples/addsubz.rb +22 -0
  24. data/lib/HDLRuby/hdr_samples/alu.rb +47 -0
  25. data/lib/HDLRuby/hdr_samples/calculator.rb +48 -0
  26. data/lib/HDLRuby/hdr_samples/counter_bench.rb +83 -0
  27. data/lib/HDLRuby/hdr_samples/dff.rb +9 -0
  28. data/lib/HDLRuby/hdr_samples/dff_bench.rb +66 -0
  29. data/lib/HDLRuby/hdr_samples/dff_counter.rb +20 -0
  30. data/lib/HDLRuby/hdr_samples/include.rb +14 -0
  31. data/lib/HDLRuby/hdr_samples/instance_open.rb +23 -0
  32. data/lib/HDLRuby/hdr_samples/mei8.rb +256 -0
  33. data/lib/HDLRuby/hdr_samples/mei8_bench.rb +309 -0
  34. data/lib/HDLRuby/hdr_samples/multer_gen.rb +8 -0
  35. data/lib/HDLRuby/hdr_samples/multer_seq.rb +29 -0
  36. data/lib/HDLRuby/hdr_samples/neural/a.rb +9 -0
  37. data/lib/HDLRuby/hdr_samples/neural/a_sub.rb +5 -0
  38. data/lib/HDLRuby/hdr_samples/neural/bw.rb +23 -0
  39. data/lib/HDLRuby/hdr_samples/neural/counter.rb +16 -0
  40. data/lib/HDLRuby/hdr_samples/neural/dadz.rb +9 -0
  41. data/lib/HDLRuby/hdr_samples/neural/dadz_sub.rb +4 -0
  42. data/lib/HDLRuby/hdr_samples/neural/forward.rb +153 -0
  43. data/lib/HDLRuby/hdr_samples/neural/forward_sub.rb +62 -0
  44. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand.rb +41 -0
  45. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand_typedef.rb +47 -0
  46. data/lib/HDLRuby/hdr_samples/neural/mem.rb +30 -0
  47. data/lib/HDLRuby/hdr_samples/neural/random.rb +23 -0
  48. data/lib/HDLRuby/hdr_samples/neural/selector.rb +29 -0
  49. data/lib/HDLRuby/hdr_samples/neural/sigmoid.rb +20 -0
  50. data/lib/HDLRuby/hdr_samples/neural/z.rb +33 -0
  51. data/lib/HDLRuby/hdr_samples/prog.obj +256 -0
  52. data/lib/HDLRuby/hdr_samples/ram.rb +18 -0
  53. data/lib/HDLRuby/hdr_samples/register_with_code_bench.rb +98 -0
  54. data/lib/HDLRuby/hdr_samples/rom.rb +10 -0
  55. data/lib/HDLRuby/hdr_samples/struct.rb +14 -0
  56. data/lib/HDLRuby/hdr_samples/sumprod.rb +29 -0
  57. data/lib/HDLRuby/hdr_samples/sw_encrypt_bench.rb +103 -0
  58. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpu_bench.rb +261 -0
  59. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpusim_bench.rb +302 -0
  60. data/lib/HDLRuby/hdr_samples/system_open.rb +11 -0
  61. data/lib/HDLRuby/hdr_samples/tuple.rb +16 -0
  62. data/lib/HDLRuby/hdr_samples/with_channel.rb +118 -0
  63. data/lib/HDLRuby/hdr_samples/with_class.rb +199 -0
  64. data/lib/HDLRuby/hdr_samples/with_decoder.rb +17 -0
  65. data/lib/HDLRuby/hdr_samples/with_fsm.rb +34 -0
  66. data/lib/HDLRuby/hdr_samples/with_reconf.rb +103 -0
  67. data/lib/HDLRuby/hdrcc.rb +623 -0
  68. data/lib/HDLRuby/high_samples/_adder_fault.rb +23 -0
  69. data/lib/HDLRuby/high_samples/_generic_transmission2.rb +146 -0
  70. data/lib/HDLRuby/high_samples/adder.rb +21 -0
  71. data/lib/HDLRuby/high_samples/adder_common_errors.rb +25 -0
  72. data/lib/HDLRuby/high_samples/addsub.rb +33 -0
  73. data/lib/HDLRuby/high_samples/addsubz.rb +37 -0
  74. data/lib/HDLRuby/high_samples/after.rb +28 -0
  75. data/lib/HDLRuby/high_samples/all_signals.rb +29 -0
  76. data/lib/HDLRuby/high_samples/alu.rb +61 -0
  77. data/lib/HDLRuby/high_samples/anonymous.rb +41 -0
  78. data/lib/HDLRuby/high_samples/before.rb +28 -0
  79. data/lib/HDLRuby/high_samples/blockblock.rb +26 -0
  80. data/lib/HDLRuby/high_samples/bugs/dadz.rb +22 -0
  81. data/lib/HDLRuby/high_samples/bugs/misample_instan.rb +20 -0
  82. data/lib/HDLRuby/high_samples/bugs/misample_updown.rb +22 -0
  83. data/lib/HDLRuby/high_samples/bugs/sample_add.rb +16 -0
  84. data/lib/HDLRuby/high_samples/bugs/sample_barrel.rb +13 -0
  85. data/lib/HDLRuby/high_samples/bugs/sample_daice.rb +57 -0
  86. data/lib/HDLRuby/high_samples/bugs/sample_kumiawase.rb +52 -0
  87. data/lib/HDLRuby/high_samples/bugs/sample_multi.rb +18 -0
  88. data/lib/HDLRuby/high_samples/bugs/sample_sub.rb +14 -0
  89. data/lib/HDLRuby/high_samples/bugs/z2.rb +32 -0
  90. data/lib/HDLRuby/high_samples/case.rb +32 -0
  91. data/lib/HDLRuby/high_samples/case2.rb +30 -0
  92. data/lib/HDLRuby/high_samples/change.rb +23 -0
  93. data/lib/HDLRuby/high_samples/clocks.rb +35 -0
  94. data/lib/HDLRuby/high_samples/comparer.rb +21 -0
  95. data/lib/HDLRuby/high_samples/conditionals.rb +29 -0
  96. data/lib/HDLRuby/high_samples/dff.rb +23 -0
  97. data/lib/HDLRuby/high_samples/each.rb +28 -0
  98. data/lib/HDLRuby/high_samples/exporter.rb +42 -0
  99. data/lib/HDLRuby/high_samples/functions.rb +60 -0
  100. data/lib/HDLRuby/high_samples/if_seq.rb +26 -0
  101. data/lib/HDLRuby/high_samples/inherit_as_dff.rb +32 -0
  102. data/lib/HDLRuby/high_samples/inherit_dff.rb +36 -0
  103. data/lib/HDLRuby/high_samples/instance.rb +37 -0
  104. data/lib/HDLRuby/high_samples/memory.rb +64 -0
  105. data/lib/HDLRuby/high_samples/multi_file.rb +27 -0
  106. data/lib/HDLRuby/high_samples/overload.rb +32 -0
  107. data/lib/HDLRuby/high_samples/paper_after.rb +49 -0
  108. data/lib/HDLRuby/high_samples/ram.rb +27 -0
  109. data/lib/HDLRuby/high_samples/registers.rb +139 -0
  110. data/lib/HDLRuby/high_samples/rom.rb +23 -0
  111. data/lib/HDLRuby/high_samples/scopeblockname.rb +37 -0
  112. data/lib/HDLRuby/high_samples/scopescope.rb +26 -0
  113. data/lib/HDLRuby/high_samples/shift.rb +31 -0
  114. data/lib/HDLRuby/high_samples/shift2.rb +40 -0
  115. data/lib/HDLRuby/high_samples/simple_instance.rb +31 -0
  116. data/lib/HDLRuby/high_samples/test_all.sh +10 -0
  117. data/lib/HDLRuby/high_samples/typedef.rb +24 -0
  118. data/lib/HDLRuby/high_samples/values.rb +70 -0
  119. data/lib/HDLRuby/high_samples/vector.rb +22 -0
  120. data/lib/HDLRuby/high_samples/with_decoder.rb +30 -0
  121. data/lib/HDLRuby/high_samples/with_fsm.rb +46 -0
  122. data/lib/HDLRuby/high_samples/with_pipe.rb +43 -0
  123. data/lib/HDLRuby/high_samples/with_seq.rb +25 -0
  124. data/lib/HDLRuby/hruby_bstr.rb +1085 -0
  125. data/lib/HDLRuby/hruby_check.rb +317 -0
  126. data/lib/HDLRuby/hruby_db.rb +432 -0
  127. data/lib/HDLRuby/hruby_error.rb +44 -0
  128. data/lib/HDLRuby/hruby_high.rb +4103 -0
  129. data/lib/HDLRuby/hruby_low.rb +4735 -0
  130. data/lib/HDLRuby/hruby_low2c.rb +1986 -0
  131. data/lib/HDLRuby/hruby_low2high.rb +738 -0
  132. data/lib/HDLRuby/hruby_low2seq.rb +248 -0
  133. data/lib/HDLRuby/hruby_low2sym.rb +126 -0
  134. data/lib/HDLRuby/hruby_low2vhd.rb +1437 -0
  135. data/lib/HDLRuby/hruby_low_bool2select.rb +295 -0
  136. data/lib/HDLRuby/hruby_low_cleanup.rb +193 -0
  137. data/lib/HDLRuby/hruby_low_fix_types.rb +437 -0
  138. data/lib/HDLRuby/hruby_low_mutable.rb +1803 -0
  139. data/lib/HDLRuby/hruby_low_resolve.rb +165 -0
  140. data/lib/HDLRuby/hruby_low_skeleton.rb +129 -0
  141. data/lib/HDLRuby/hruby_low_with_bool.rb +141 -0
  142. data/lib/HDLRuby/hruby_low_with_port.rb +167 -0
  143. data/lib/HDLRuby/hruby_low_with_var.rb +302 -0
  144. data/lib/HDLRuby/hruby_low_without_bit2vector.rb +88 -0
  145. data/lib/HDLRuby/hruby_low_without_concat.rb +162 -0
  146. data/lib/HDLRuby/hruby_low_without_connection.rb +113 -0
  147. data/lib/HDLRuby/hruby_low_without_namespace.rb +718 -0
  148. data/lib/HDLRuby/hruby_low_without_outread.rb +107 -0
  149. data/lib/HDLRuby/hruby_low_without_select.rb +206 -0
  150. data/lib/HDLRuby/hruby_serializer.rb +398 -0
  151. data/lib/HDLRuby/hruby_tools.rb +37 -0
  152. data/lib/HDLRuby/hruby_types.rb +239 -0
  153. data/lib/HDLRuby/hruby_values.rb +64 -0
  154. data/lib/HDLRuby/hruby_verilog.rb +1888 -0
  155. data/lib/HDLRuby/hruby_verilog_name.rb +52 -0
  156. data/lib/HDLRuby/low_samples/adder.yaml +97 -0
  157. data/lib/HDLRuby/low_samples/after.yaml +228 -0
  158. data/lib/HDLRuby/low_samples/before.yaml +223 -0
  159. data/lib/HDLRuby/low_samples/blockblock.yaml +48 -0
  160. data/lib/HDLRuby/low_samples/bugs/sample_add.yaml +97 -0
  161. data/lib/HDLRuby/low_samples/bugs/sample_daice.yaml +444 -0
  162. data/lib/HDLRuby/low_samples/bugs/sample_kumiawase.yaml +332 -0
  163. data/lib/HDLRuby/low_samples/bugs/sample_sub.yaml +97 -0
  164. data/lib/HDLRuby/low_samples/bugs/seqpar.yaml +184 -0
  165. data/lib/HDLRuby/low_samples/case.yaml +327 -0
  166. data/lib/HDLRuby/low_samples/change.yaml +135 -0
  167. data/lib/HDLRuby/low_samples/clocks.yaml +674 -0
  168. data/lib/HDLRuby/low_samples/cloner.rb +22 -0
  169. data/lib/HDLRuby/low_samples/comparer.yaml +85 -0
  170. data/lib/HDLRuby/low_samples/conditionals.yaml +133 -0
  171. data/lib/HDLRuby/low_samples/dff.yaml +107 -0
  172. data/lib/HDLRuby/low_samples/each.yaml +1328 -0
  173. data/lib/HDLRuby/low_samples/exporter.yaml +226 -0
  174. data/lib/HDLRuby/low_samples/functions.yaml +298 -0
  175. data/lib/HDLRuby/low_samples/generic_transmission.yaml +597 -0
  176. data/lib/HDLRuby/low_samples/inherit_as_dff.yaml +125 -0
  177. data/lib/HDLRuby/low_samples/inherit_dff.yaml +107 -0
  178. data/lib/HDLRuby/low_samples/load_yaml.rb +11 -0
  179. data/lib/HDLRuby/low_samples/memory.yaml +678 -0
  180. data/lib/HDLRuby/low_samples/namespace_extractor.rb +23 -0
  181. data/lib/HDLRuby/low_samples/overload.yaml +226 -0
  182. data/lib/HDLRuby/low_samples/paper_after.yaml +431 -0
  183. data/lib/HDLRuby/low_samples/port_maker.rb +14 -0
  184. data/lib/HDLRuby/low_samples/ram.yaml +207 -0
  185. data/lib/HDLRuby/low_samples/registers.yaml +228 -0
  186. data/lib/HDLRuby/low_samples/rom.yaml +2950 -0
  187. data/lib/HDLRuby/low_samples/shift.yaml +230 -0
  188. data/lib/HDLRuby/low_samples/shift2.yaml +2095 -0
  189. data/lib/HDLRuby/low_samples/simple_instance.yaml +102 -0
  190. data/lib/HDLRuby/low_samples/test_all.sh +43 -0
  191. data/lib/HDLRuby/low_samples/typedef.yaml +115 -0
  192. data/lib/HDLRuby/low_samples/values.yaml +577 -0
  193. data/lib/HDLRuby/low_samples/variable_maker.rb +14 -0
  194. data/lib/HDLRuby/low_samples/vector.yaml +56 -0
  195. data/lib/HDLRuby/low_samples/with_seq.yaml +188 -0
  196. data/lib/HDLRuby/low_samples/yaml2hdr.rb +10 -0
  197. data/lib/HDLRuby/low_samples/yaml2vhd.rb +19 -0
  198. data/lib/HDLRuby/sim/Makefile +19 -0
  199. data/lib/HDLRuby/sim/hruby_sim.h +590 -0
  200. data/lib/HDLRuby/sim/hruby_sim_calc.c +2362 -0
  201. data/lib/HDLRuby/sim/hruby_sim_core.c +589 -0
  202. data/lib/HDLRuby/sim/hruby_sim_list.c +93 -0
  203. data/lib/HDLRuby/sim/hruby_sim_vizualize.c +91 -0
  204. data/lib/HDLRuby/sim/hruby_value_pool.c +64 -0
  205. data/lib/HDLRuby/std/channel.rb +354 -0
  206. data/lib/HDLRuby/std/clocks.rb +165 -0
  207. data/lib/HDLRuby/std/counters.rb +82 -0
  208. data/lib/HDLRuby/std/decoder.rb +214 -0
  209. data/lib/HDLRuby/std/fsm.rb +516 -0
  210. data/lib/HDLRuby/std/pipeline.rb +220 -0
  211. data/lib/HDLRuby/std/reconf.rb +309 -0
  212. data/lib/HDLRuby/test_hruby_bstr.rb +2259 -0
  213. data/lib/HDLRuby/test_hruby_high.rb +594 -0
  214. data/lib/HDLRuby/test_hruby_high_low.rb +99 -0
  215. data/lib/HDLRuby/test_hruby_low.rb +934 -0
  216. data/lib/HDLRuby/v_samples/adder.v +10 -0
  217. data/lib/HDLRuby/v_samples/dff.v +12 -0
  218. data/lib/HDLRuby/v_samples/ram.v +20 -0
  219. data/lib/HDLRuby/v_samples/rom.v +270 -0
  220. data/lib/HDLRuby/version.rb +3 -0
  221. data/lib/HDLRuby.rb +11 -0
  222. data/makedoc +1 -0
  223. data/metadata.yaml +4 -0
  224. metadata +299 -0
@@ -0,0 +1,589 @@
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+ #include <limits.h>
5
+ #include <pthread.h>
6
+
7
+ #include "hruby_sim.h"
8
+
9
+
10
+ /**
11
+ * The HDLRuby simulation core, to be used with C code generated by
12
+ * hruby_low2c.
13
+ * */
14
+
15
+ /** The number of all the signals. */
16
+ static int num_all_signals = 0;
17
+ /** The capacity of the set of signals. */
18
+ static int cap_all_signals = 0;
19
+ /** The set of all the signals. */
20
+ static SignalI* all_signals = NULL;
21
+
22
+ /** The list of touched signals. */
23
+ static ListS touched_signals_content = { NULL, NULL };
24
+ static List touched_signals = &touched_signals_content;
25
+
26
+ /** The list of touched signals in the sequential execution model. */
27
+ static ListS touched_signals_seq_content = { NULL, NULL };
28
+ static List touched_signals_seq = &touched_signals_seq_content;
29
+
30
+
31
+ /** The list of activated code. */
32
+ static ListS activate_codes_content = { NULL, NULL };
33
+ static List activate_codes = &activate_codes_content;
34
+
35
+ /** The number of timed behaviors. */
36
+ static int num_timed_behaviors = 0;
37
+ /** The capacity of the timed behaviors. */
38
+ static int cap_timed_behaviors = 0;
39
+ /** The timed behaviors. */
40
+ static Behavior* timed_behaviors = NULL;
41
+
42
+ /** The number of running behaviors. */
43
+ static int num_run_behaviors = 0;
44
+ /** The number of activated behaviors. */
45
+ static int num_active_behaviors = 0;
46
+
47
+ /** Flag saying the behaviors can run. */
48
+ static int behaviors_can_run = 0;
49
+
50
+ /** The current simulation time. */
51
+ static unsigned long long hruby_sim_time = 0;
52
+
53
+ /** The mutex for accessing the simulator ressources. */
54
+ static pthread_mutex_t hruby_sim_mutex = PTHREAD_MUTEX_INITIALIZER;
55
+
56
+ /** The condition the behaviors wait on. */
57
+ static pthread_cond_t hruby_beh_cond = PTHREAD_COND_INITIALIZER;
58
+ /** The condition the simulator waits on. */
59
+ static pthread_cond_t hruby_sim_cond = PTHREAD_COND_INITIALIZER;
60
+
61
+ /** Flags for the simulation. */
62
+ static int sim_end_flag = 0;
63
+
64
+ /** Adds a timed behavior for processing.
65
+ * @param behavior the timed behavior to register */
66
+ void register_timed_behavior(Behavior behavior) {
67
+ if (num_timed_behaviors == cap_timed_behaviors) {
68
+ if (cap_timed_behaviors == 0) {
69
+ /* Need to create the array containing the timed behaviors. */
70
+ cap_timed_behaviors = 5;
71
+ timed_behaviors = calloc(sizeof(Behavior),cap_timed_behaviors);
72
+ } else {
73
+ /* Need to increase the capacity. */
74
+ Behavior* behaviors = calloc(sizeof(Behavior),cap_timed_behaviors*2);
75
+ memcpy(timed_behaviors,behaviors,sizeof(Behavior)*cap_timed_behaviors);
76
+ cap_timed_behaviors *= 2;
77
+ }
78
+ }
79
+ /* Add the behavior. */
80
+ timed_behaviors[num_timed_behaviors++] = behavior;
81
+ }
82
+
83
+
84
+ /** Adds a signal for global processing.
85
+ * @param signal the signal to register */
86
+ void register_signal(SignalI signal) {
87
+ if (num_all_signals == cap_all_signals) {
88
+ if (cap_all_signals == 0) {
89
+ /* Need to create the array containing the timed behaviors. */
90
+ cap_all_signals = 100;
91
+ all_signals = calloc(sizeof(SignalI),cap_all_signals);
92
+ } else {
93
+ /* Need to increase the capacity. */
94
+ Behavior* behaviors = calloc(sizeof(Behavior),cap_all_signals*2);
95
+ memcpy(all_signals,behaviors,sizeof(Behavior)*cap_all_signals);
96
+ cap_all_signals *= 2;
97
+ }
98
+ }
99
+ /* Add the behavior. */
100
+ all_signals[num_all_signals++] = signal;
101
+ }
102
+
103
+
104
+ /** Recursively update the signals until no (untimed) behavior are
105
+ * activated. */
106
+ void hruby_sim_update_signals() {
107
+ // printf("hruby_sim_update_signals...\n");
108
+ /* As long as the list of touched signals is not empty go on computing. */
109
+ while(!empty_list(touched_signals) || !empty_list(touched_signals_seq)) {
110
+ // printf("## Checking touched signals.\n");
111
+ /* Sets the new signals values and mark the signals as activating. */
112
+ /* For the case of the parallel execution model. */
113
+ while(!empty_list(touched_signals)) {
114
+ Elem e = remove_list(touched_signals);
115
+ SignalI sig = e->data;
116
+ delete_element(e);
117
+ /* Is there a change? */
118
+ if (same_content_value(sig->c_value,sig->f_value)) continue;
119
+ /* Yes, process the signal. */
120
+ println_signal(sig);
121
+ // printf("c_value="); print_value(sig->c_value);
122
+ // printf("\nf_value="); print_value(sig->f_value); printf("\n");
123
+ // printf("Touched signal: %p (%s)\n",sig,sig->name);
124
+ /* Update the current value of the signal. */
125
+ copy_value(sig->f_value,sig->c_value);
126
+ // /* Mark the signal as activated. */
127
+ // add_list(activate_signals,e);
128
+ /* Mark the corresponding code as activated. */
129
+ /* Any edge activation. */
130
+ int i;
131
+ for(i=0; i<sig->num_any; ++i) {
132
+ Object obj = sig->any[i];
133
+ if (obj->kind == BEHAVIOR) {
134
+ /* Behavior case. */
135
+ Behavior beh = (Behavior)obj;
136
+ beh->activated = 1;
137
+ add_list(activate_codes,get_element(beh));
138
+ } else {
139
+ /* Other code case. */
140
+ Code cod = (Code)obj;
141
+ cod->activated = 1;
142
+ add_list(activate_codes,get_element(cod));
143
+ }
144
+ }
145
+ /* Positive edge activation. */
146
+ if (!zero_value(sig->c_value)) {
147
+ for(i=0; i<sig->num_pos; ++i) {
148
+ Object obj = sig->pos[i];
149
+ if (obj->kind == BEHAVIOR) {
150
+ /* Behavior case. */
151
+ Behavior beh = (Behavior)obj;
152
+ beh->activated = 1;
153
+ add_list(activate_codes,get_element(beh));
154
+ } else {
155
+ /* Other code case. */
156
+ Code cod = (Code)obj;
157
+ cod->activated = 1;
158
+ add_list(activate_codes,get_element(cod));
159
+ }
160
+ }
161
+ }
162
+ /* Negative edge activation. */
163
+ if (zero_value(sig->c_value)) {
164
+ for(i=0; i<sig->num_neg; ++i) {
165
+ Object obj = sig->neg[i];
166
+ if (obj->kind == BEHAVIOR) {
167
+ /* Behavior case. */
168
+ Behavior beh = (Behavior)obj;
169
+ beh->activated = 1;
170
+ add_list(activate_codes,get_element(beh));
171
+ } else {
172
+ /* Other code case. */
173
+ Code cod = (Code)obj;
174
+ cod->activated = 1;
175
+ add_list(activate_codes,get_element(cod));
176
+ }
177
+ }
178
+ }
179
+ }
180
+ /* And fdor the case of the sequential execution model
181
+ * (no more content check nor update of current value necessary). */
182
+ while(!empty_list(touched_signals_seq)) {
183
+ Elem e = remove_list(touched_signals_seq);
184
+ SignalI sig = e->data;
185
+ delete_element(e);
186
+ /* Yes, process the signal. */
187
+ println_signal(sig);
188
+ /* Update the current value of the signal. */
189
+ /* Mark the corresponding code as activated. */
190
+ /* Any edge activation. */
191
+ int i;
192
+ for(i=0; i<sig->num_any; ++i) {
193
+ Object obj = sig->any[i];
194
+ if (obj->kind == BEHAVIOR) {
195
+ /* Behavior case. */
196
+ Behavior beh = (Behavior)obj;
197
+ beh->activated = 1;
198
+ add_list(activate_codes,get_element(beh));
199
+ } else {
200
+ /* Other code case. */
201
+ Code cod = (Code)obj;
202
+ cod->activated = 1;
203
+ add_list(activate_codes,get_element(cod));
204
+ }
205
+ }
206
+ /* Positive edge activation. */
207
+ if (!zero_value(sig->c_value)) {
208
+ for(i=0; i<sig->num_pos; ++i) {
209
+ Object obj = sig->pos[i];
210
+ if (obj->kind == BEHAVIOR) {
211
+ /* Behavior case. */
212
+ Behavior beh = (Behavior)obj;
213
+ beh->activated = 1;
214
+ add_list(activate_codes,get_element(beh));
215
+ } else {
216
+ /* Other code case. */
217
+ Code cod = (Code)obj;
218
+ cod->activated = 1;
219
+ add_list(activate_codes,get_element(cod));
220
+ }
221
+ }
222
+ }
223
+ /* Negative edge activation. */
224
+ if (zero_value(sig->c_value)) {
225
+ for(i=0; i<sig->num_neg; ++i) {
226
+ Object obj = sig->neg[i];
227
+ if (obj->kind == BEHAVIOR) {
228
+ /* Behavior case. */
229
+ Behavior beh = (Behavior)obj;
230
+ beh->activated = 1;
231
+ add_list(activate_codes,get_element(beh));
232
+ } else {
233
+ /* Other code case. */
234
+ Code cod = (Code)obj;
235
+ cod->activated = 1;
236
+ add_list(activate_codes,get_element(cod));
237
+ }
238
+ }
239
+ }
240
+ }
241
+
242
+ // printf("## Checking activate codes.\n");
243
+ /* Execute the behaviors activated by the signals. */
244
+ while(!empty_list(activate_codes)) {
245
+ Elem e = remove_list(activate_codes);
246
+ Object obj = e->data;
247
+ delete_element(e);
248
+ if (obj->kind == BEHAVIOR) {
249
+ /* Behavior case. */
250
+ Behavior beh = (Behavior)obj;
251
+ /* Is the code really activated? */
252
+ if (beh->activated) {
253
+ /* Yes, execute it. */
254
+ beh->block->function();
255
+ /* And deactivate it. */
256
+ beh->activated = 0;
257
+ }
258
+ } else {
259
+ /* Other code case. */
260
+ Code cod = (Code)obj;
261
+ /* Is the code really activated? */
262
+ if (cod->activated) {
263
+ /* Yes, execute it. */
264
+ cod->function();
265
+ /* And deactivate it. */
266
+ cod->activated = 0;
267
+ }
268
+ }
269
+ }
270
+ }
271
+ }
272
+
273
+
274
+ /** Advance time to the next time step. */
275
+ void hruby_sim_advance_time() {
276
+ /* Collects the activation time of all the timed behaviors and find
277
+ * the shortest one. */
278
+ unsigned long long next_time = ULLONG_MAX;
279
+ int i;
280
+ for(i=0; i<num_timed_behaviors; ++i) {
281
+ unsigned long long beh_time = timed_behaviors[i]->active_time;
282
+ if (beh_time < next_time) next_time = beh_time;
283
+ }
284
+ /* Sets the new activation time. */
285
+ hruby_sim_time = next_time;
286
+ println_time(hruby_sim_time);
287
+ }
288
+
289
+
290
+ /** Activates a behavior.
291
+ * @param behavior the behavior to activate. */
292
+ void activate_behavior(Behavior behavior) {
293
+
294
+ }
295
+
296
+
297
+ /** Activates the timed behavior that have to be activated at this
298
+ * time. */
299
+ void hruby_sim_activate_behaviors_on_time() {
300
+ int i;
301
+ // printf("$1\n");
302
+ pthread_mutex_lock(&hruby_sim_mutex);
303
+ /* Count the number of behaviors that will be activated. */
304
+ for(i=0; i<num_timed_behaviors; ++i) {
305
+ Behavior beh = timed_behaviors[i];
306
+ if (beh->active_time == hruby_sim_time) {
307
+ /* Increase the number of timed behavior to wait for. */
308
+ num_active_behaviors ++;
309
+ // printf("num_active_behaviors = %d\n",num_active_behaviors);
310
+ }
311
+ }
312
+ /* Activate the behaviors .*/
313
+ behaviors_can_run = 1;
314
+ // pthread_cond_signal(&compute_cond); /* No behaviors. */
315
+ pthread_cond_signal(&hruby_beh_cond);
316
+ pthread_mutex_unlock(&hruby_sim_mutex);
317
+ // printf("$2\n");
318
+ }
319
+
320
+
321
+ /** Wait for the active timed behaviors to advance. */
322
+ void hruby_sim_wait_behaviors() {
323
+ // printf("$3\n");
324
+ pthread_mutex_lock(&hruby_sim_mutex);
325
+ while(num_active_behaviors > 0) {
326
+ // printf("num_active_behaviors = %d\n",num_active_behaviors);
327
+ // pthread_cond_wait(&active_behaviors_cond, &hruby_sim_mutex);
328
+ pthread_cond_wait(&hruby_sim_cond, &hruby_sim_mutex);
329
+ }
330
+ behaviors_can_run = 0;
331
+ pthread_mutex_unlock(&hruby_sim_mutex);
332
+ // printf("$4\n");
333
+ }
334
+
335
+
336
+ /** The code for starting a behavior.
337
+ * @param arg the behavior to execute. */
338
+ void* behavior_run(void* arg) {
339
+ Behavior behavior = (Behavior)arg;
340
+ /* First lock the behavior until the simulation engine starts. */
341
+ // printf("#1\n");
342
+ pthread_mutex_lock(&hruby_sim_mutex);
343
+ num_active_behaviors -= 1;
344
+ while(!behaviors_can_run) {
345
+ // pthread_cond_wait(&compute_cond, &hruby_sim_mutex);
346
+ pthread_cond_wait(&hruby_beh_cond, &hruby_sim_mutex);
347
+ }
348
+ pthread_mutex_unlock(&hruby_sim_mutex);
349
+ // printf("#2\n");
350
+ /* Now can start the execution of the behavior. */
351
+ behavior->block->function();
352
+ /* Stops the behavior. */
353
+ pthread_mutex_lock(&hruby_sim_mutex);
354
+ num_active_behaviors -= 1;
355
+ num_run_behaviors -= 1;
356
+ pthread_cond_signal(&hruby_sim_cond);
357
+ pthread_mutex_unlock(&hruby_sim_mutex);
358
+ /* End the thread. */
359
+ pthread_exit(NULL);
360
+ }
361
+
362
+
363
+ /** Starts the timed behaviors.
364
+ * @note create a thread per timed behavior. */
365
+ void hruby_sim_start_timed_behaviors() {
366
+ int i;
367
+ /* Sets the end flags to 0. */
368
+ sim_end_flag = 0;
369
+ /* Create and start the threads. */
370
+ for(i=0; i<num_timed_behaviors; ++i) {
371
+ num_run_behaviors += 1;
372
+ // ++num_active_behaviors;
373
+ // printf("0 num_active_behaviors = %d\n",num_active_behaviors);
374
+ pthread_create(&timed_behaviors[i]->thread,NULL,
375
+ &behavior_run,timed_behaviors[i]);
376
+ }
377
+ }
378
+
379
+ /** Ends waiting all the threads properly terminates. */
380
+ void hruby_sim_end_timed_behaviors() {
381
+ int i;
382
+ /* Sets the end flag to 1. */
383
+ sim_end_flag = 1;
384
+ /* Wait for the threads to terminate. */
385
+ for(i=0; i<num_timed_behaviors; ++i) {
386
+ pthread_join(timed_behaviors[i]->thread,NULL);
387
+ }
388
+ }
389
+
390
+
391
+
392
+
393
+ /** The simulation core function.
394
+ * @param limit the time limit in fs. */
395
+ void hruby_sim_core(unsigned long long limit) {
396
+ /* Initialize the time to 0. */
397
+ hruby_sim_time = 0;
398
+
399
+ /* Start all the timed behaviors. */
400
+ hruby_sim_start_timed_behaviors();
401
+ // /* Activate the timed behavior that are on time. */
402
+ // hruby_sim_activate_behaviors_on_time();
403
+
404
+ /* Run while there are active behaviors and the time limit is not
405
+ * reached */
406
+ while(hruby_sim_time<limit) {
407
+ int i;
408
+ // printf("num_active_behaviors = %d\n",num_active_behaviors);
409
+ /* Wait for the active timed behaviors to perform their computations. */
410
+ hruby_sim_wait_behaviors();
411
+ /* Update the signal values (recursively executing blocks locked
412
+ * on the signals). */
413
+ hruby_sim_update_signals();
414
+ if (num_run_behaviors <= 0) break;
415
+ /* Advance time to next timestep. */
416
+ hruby_sim_advance_time();
417
+
418
+ /* Mark the signals as fading. */
419
+ for(i=0; i<num_all_signals; ++i) {
420
+ all_signals[i]->fading = 1;
421
+ }
422
+
423
+ /* Activate the timed behavior that are on time. */
424
+ hruby_sim_activate_behaviors_on_time();
425
+ }
426
+ }
427
+
428
+
429
+
430
+
431
+ /* ##################################################################### */
432
+ /* ## The interface for the HW description. ## */
433
+ /* ##################################################################### */
434
+
435
+
436
+
437
+
438
+ /** Makes the behavior wait for a given time.
439
+ * @param delay the delay to wait in fs.
440
+ * @param behavior the current behavior. */
441
+ void hw_wait(unsigned long long delay, Behavior behavior) {
442
+ // printf("!1\n");
443
+ /* Maybe the thread is to end immediatly. */
444
+ if (sim_end_flag)
445
+ pthread_exit(NULL);
446
+ /* No go on with the wait procedure. */
447
+ pthread_mutex_lock(&hruby_sim_mutex);
448
+ /* Indicate the behavior finished current execution. */
449
+ num_active_behaviors -= 1;
450
+ pthread_cond_signal(&hruby_sim_cond);
451
+ /* Update the behavior's time. */
452
+ behavior->active_time += delay;
453
+ pthread_mutex_unlock(&hruby_sim_mutex);
454
+ /* Wait for being reactivated. */
455
+ while(behavior->active_time > hruby_sim_time) {
456
+ pthread_mutex_lock(&hruby_sim_mutex);
457
+ while(!behaviors_can_run) {
458
+ // pthread_cond_wait(&compute_cond, &hruby_sim_mutex);
459
+ pthread_cond_wait(&hruby_beh_cond, &hruby_sim_mutex);
460
+ }
461
+ pthread_mutex_unlock(&hruby_sim_mutex);
462
+ }
463
+ }
464
+
465
+
466
+ /** Touch a signal.
467
+ * @param signal the signal to touch */
468
+ void touch_signal(SignalI signal) {
469
+ // printf("touching signal: %p\n",signal);
470
+ add_list(touched_signals,get_element(signal));
471
+ // println_signal(signal);
472
+ /* Now the signal is not fading any longer. */
473
+ signal->fading = 0;
474
+ }
475
+
476
+
477
+ /** Transmit a value to a signal.
478
+ * @param value the value to transmit
479
+ * @param signal the signal to transmit the value to. */
480
+ void transmit_to_signal(Value value, SignalI signal) {
481
+ // printf("Tansmit to signal: %s(%p) with fading=%d\n",signal->name,signal,signal->fading);
482
+ /* Copy the content. */
483
+ if (signal->fading)
484
+ signal->f_value = copy_value(value,signal->f_value);
485
+ else
486
+ signal->f_value = copy_value_no_z(value,signal->f_value);
487
+ /* And touch the signal. */
488
+ touch_signal(signal);
489
+ }
490
+
491
+ /** Transmit a value to a range within a signal.
492
+ * @param value the value to transmit
493
+ * @param ref the reference to the range in the signal to transmit the
494
+ * value to. */
495
+ void transmit_to_signal_range(Value value, RefRangeS ref) {
496
+ SignalI signal = ref.signal;
497
+ unsigned long long first = ref.first;
498
+ unsigned long long last = ref.last;
499
+ // printf("Tansmit to signal range: %s(%p)\n",signal->name,signal);
500
+ /* Can transmit, copy the content. */
501
+ if (signal->fading)
502
+ signal->f_value = write_range(value,first,last,signal->f_value);
503
+ else
504
+ signal->f_value = write_range_no_z(value,first,last,signal->f_value);
505
+ /* And touch the signal. */
506
+ touch_signal(signal);
507
+ }
508
+
509
+
510
+
511
+ /** Touch a signal in case of sequential execution model.
512
+ * @param signal the signal to touch */
513
+ void touch_signal_seq(SignalI signal) {
514
+ // printf("touching signal seq: %p\n",signal);
515
+ /* Is there a difference between the present and future value? */
516
+ if (same_content_value(signal->c_value,signal->f_value)) return;
517
+ /* Yes, add the signal to the list of touched sequential ones and update
518
+ * its current value. */
519
+ add_list(touched_signals_seq,get_element(signal));
520
+ copy_value(signal->f_value,signal->c_value);
521
+ // println_signal(signal);
522
+ /* Now the signal is not fading any longer. */
523
+ signal->fading = 0;
524
+ }
525
+
526
+
527
+ /** Transmit a value to a signal in case of a sequential execution model.
528
+ * @param value the value to transmit
529
+ * @param signal the signal to transmit the value to. */
530
+ void transmit_to_signal_seq(Value value, SignalI signal) {
531
+ // printf("Tansmit to signal seq: %s(%p)\n",signal->name,signal);
532
+ /* Copy the content. */
533
+ if (signal->fading)
534
+ copy_value(value,signal->f_value);
535
+ else
536
+ copy_value_no_z(value,signal->f_value);
537
+ /* And touch the signal. */
538
+ touch_signal_seq(signal);
539
+ }
540
+
541
+ /** Transmit a value to a range within a signal in case of sequential
542
+ * execution model.
543
+ * @param value the value to transmit
544
+ * @param ref the reference to the range in the signal to transmit the
545
+ * value to. */
546
+ void transmit_to_signal_range_seq(Value value, RefRangeS ref) {
547
+ SignalI signal = ref.signal;
548
+ unsigned long long first = ref.first;
549
+ unsigned long long last = ref.last;
550
+ // printf("Tansmit to signal range: %s(%p)\n",signal->name,signal);
551
+ /* Can transmit, copy the content. */
552
+ if (signal->fading)
553
+ write_range(value,first,last,signal->f_value);
554
+ else
555
+ write_range_no_z(value,first,last,signal->f_value);
556
+ /* And touch the signal. */
557
+ touch_signal_seq(signal);
558
+ }
559
+
560
+ /** Creates an event.
561
+ * @param edge the edge of the event
562
+ * @param signal the signal of the event */
563
+ Event make_event(Edge edge, SignalI signal) {
564
+ Event event = malloc(sizeof(EventS));
565
+ event->edge = edge;
566
+ event->signal = signal;
567
+
568
+ return event;
569
+ }
570
+
571
+
572
+ /** Creates a delay.
573
+ * Actually generates an unsigned long long giving the corresponding
574
+ * delay in the base unit of the simulator.
575
+ * @param value the value of the delay
576
+ * @param unit the used unit
577
+ * @return the result delay in the base unit of the simulator (ns) */
578
+ unsigned long long make_delay(int value, Unit unit) {
579
+ switch(unit) {
580
+ case S: return value * 1000000000ULL;
581
+ case MS: return value * 1000000ULL;
582
+ case US: return value * 1000ULL;
583
+ case NS: return value * 1ULL;
584
+ default:
585
+ perror("Invalid unit for a delay.");
586
+ }
587
+ return -1;
588
+ }
589
+
@@ -0,0 +1,93 @@
1
+ #include <stdlib.h>
2
+
3
+ #include "hruby_sim.h"
4
+
5
+ /**
6
+ * The lists used in HDLRuby simulation, to be used with C code generated by
7
+ * hruby_low2c.
8
+ * */
9
+
10
+
11
+ /* The pool of list elements to reduce number of memory allocations. */
12
+ static ListS pool_elements = { NULL, NULL };
13
+
14
+ /** Get a list element for containing some data.
15
+ * @param data the data of the element
16
+ * @return the resulting element */
17
+ Elem get_element(void* data) {
18
+ Elem elem; /* The resulting element. */
19
+ /* Is the pool empty? */
20
+ if (empty_list(&pool_elements)) {
21
+ /* Yes, allocates a new element. */
22
+ elem = malloc(sizeof(ElemS));
23
+ elem->data = data;
24
+ elem->next = NULL;
25
+ } else {
26
+ /* No, get the element from the pool. */
27
+ elem = pool_elements.head;
28
+ elem->data = data;
29
+ elem->next = NULL;
30
+ pool_elements.head = pool_elements.head->next;
31
+ if (pool_elements.tail == elem)
32
+ pool_elements.tail = NULL;
33
+ }
34
+ return elem;
35
+ }
36
+
37
+ /** Delete an element (it will return to the pool).
38
+ * @param elem the element to delete */
39
+ void delete_element(Elem elem) {
40
+ elem->data = NULL;
41
+ add_list(&pool_elements,elem);
42
+ }
43
+
44
+
45
+ /** Builds a list.
46
+ * @param list the place where to build the list
47
+ * @return the resulting list */
48
+ List build_list(List list) {
49
+ list->head = list->tail = NULL;
50
+ return list;
51
+ }
52
+
53
+ /** Clears a list.
54
+ * @param list the list to clear */
55
+ void clear_list(List list) {
56
+ list->head = list->tail = NULL;
57
+ }
58
+
59
+ /** Adds an element to the tail of a list.
60
+ * @param list the list to add the element in
61
+ * @param elem the element to add in the list */
62
+ void add_list(List list, Elem elem) {
63
+ /* Ensures the element is unlinked. */
64
+ elem->next = NULL;
65
+ /* Is the list empty? */
66
+ if (empty_list(list)) {
67
+ /* Yes, the element is the head and the tail. */
68
+ list->head = list->tail = elem;
69
+ } else {
70
+ /* No, simply add to the tail. */
71
+ list->tail->next = elem;
72
+ list->tail = elem;
73
+ }
74
+ }
75
+
76
+ /** Remove the head of the list.
77
+ * @param list the list to remove the head from
78
+ * @return the removed element */
79
+ Elem remove_list(List list) {
80
+ /* Is the list empty? */
81
+ if (empty_list(list)) {
82
+ /* Yes, no element to remove. */
83
+ return NULL;
84
+ } else {
85
+ /* No, remove the head. */
86
+ Elem elem = list->head;
87
+ list->head = list->head->next;
88
+ if (list->tail == elem) {
89
+ list->tail = NULL;
90
+ }
91
+ return elem;
92
+ }
93
+ }