HDLRuby 3.7.8 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 343e43059315343f17e5999397af265b9d7c241ce527c57855b4b7d24d4c698a
4
- data.tar.gz: d21dd89efe29eb843ad69c20ae802bad2c11d9d2ad5f6a2d96a904cdd72b9b33
3
+ metadata.gz: b3ecb1e50d09ad4ec7aa0809f93da534ce0672c30240aa9405124a075d29a015
4
+ data.tar.gz: 3b939a8ad0eeef795473657775a83c265597fa13939dae1c91bff685ab6024b4
5
5
  SHA512:
6
- metadata.gz: 0ebc27526e8c259b80a40171e7eb65fa529c477621366296926acbb266f20dd44a55cff96a875cf77cf7c3d739d2d7f252281fec9671a06400829ae01f84883b
7
- data.tar.gz: 36e07d94b685e170b815ca07f1e2c8e50b580b02c49602e8737aced082e606b3c269e1173c9ed92dee89d53418f1dc3a04491d0d9510992e4f04088062fca15e
6
+ metadata.gz: 60bf1dcdf1243053841f7033398fce2de880bb412b19142b2356ceaf05261adfde4cac6afe5a861b1026b30139836210c5fa42e496ba2d563822bf05b0333839
7
+ data.tar.gz: e6c56348b4e2cfa38cd0778e4d5d091b983c39b82af33df3cb11883f7ac5a40af920856cc2d9e8a2d79ee6084a82106d03c198c52a51456729d702ec67a8c819
data/README.md CHANGED
@@ -17,6 +17,21 @@ hdrcc --get-tuto
17
17
 
18
18
  __What's new_
19
19
 
20
+ For HDLRuby version 3.8.0:
21
+
22
+ * Added parallel enumerators (e.g., heach): can iterate like Ruby for describing parallel hardware.
23
+
24
+ * Added metaprogramming through standard HDLRuby constructs (e.g., hif): no need to use Ruby code any longer.
25
+
26
+ * Fixed compile bugs for windows.
27
+
28
+
29
+ For HDLRuby version 3.7.9:
30
+
31
+ * Added Python code generation from the software sequencers.
32
+
33
+ * Added [parallel enumerators](#parallel-enumerators-stdhruby_enumrb).
34
+
20
35
  For HDLRuby versions 3.7.7/3.7.8:
21
36
 
22
37
  * Various fixes regqrding the software sequencers.
@@ -3256,6 +3271,125 @@ fsm(clk.posedge,rst,:static)
3256
3271
  end
3257
3272
  ```
3258
3273
 
3274
+
3275
+ ## Parallel Enumerators:: `std/hruby_enum.rb`
3276
+ <a name="enumertor"></a>
3277
+
3278
+ HDLRuby parallel enumerators are objects for generating hardware processing series of signals in parallel. They are created using the method `heach` on parallel enumerable objects.
3279
+
3280
+ Parallel enumerable objects include, arrays of signals and ranges.
3281
+ A parallel enumerable object can also be generated from an integer values using one of the following method:
3282
+
3283
+
3284
+ - `<integer>.htimes`: is equivalent to the range `0..<integer-1>`.
3285
+
3286
+ - `<integer>.supto(<last>)`: is equivalent to the range `<integer>..<last>`.
3287
+
3288
+ - `<integer>.sdownto(<last>)`: is equivalent to the range `<last>..<integer>`.
3289
+
3290
+ The parallel enumerators can be controlled using the following methods:
3291
+
3292
+ - `hsize`: returns the number of elements the enumerator can access.
3293
+
3294
+ - `htype`: returns the type of the elements accessed by the enumerator.
3295
+
3296
+ - `heach`: returns the current enumerator. If a block is given, it performs the iteration instead of returning an enumerator.
3297
+
3298
+ - `heach_with_index`: returns an enumerator over the elements of the current enumerator associated with their index position. If a block is given, it performs the iteration instead of returning an enumerator.
3299
+
3300
+ - `heach_with_object(<obj>)`: returns an enumerator over the elements of the current enumerator associated with object `obj` (any object, HDLRuby or not, can be used). If a block is given, it performs the iteration instead of returning an enumerator.
3301
+
3302
+ - `with_index`: identical to `seach_with_index`.
3303
+
3304
+ - `with_object(<obj>)`: identical to `seach_with_object`.
3305
+
3306
+ - `clone`: create a new enumerator on the same elements.
3307
+
3308
+ - `+`: concatenation of enumerators.
3309
+
3310
+
3311
+ With this basis, several algorithms have been implemented using enumerators and are usable for all the enumerable objects inside and outside proceses. All these algorithms are HW implantation of the Ruby Enumerable methods. They are accessible using the corresponding ruby method prefixed by character `h`. For example, the HW implementation of the ruby `all?` method is generated by the `hall?` method. In details:
3312
+
3313
+ - `hall?`: HW implementation of the Ruby `all?` method. Returns a single-bit signal. When 0 this value means false and when 1 it means true.
3314
+
3315
+ - `hany?`: HW implementation of the Ruby `any?` method. Returns a single-bit signal. When 0 this value means false and when 1 it means true.
3316
+
3317
+ - `hchain`: HW implementation of the Ruby `chain`.
3318
+
3319
+ - `hmap`: HW implementation of the Ruby `map` method. When used with a block returns a vector signal containing each computation result.
3320
+
3321
+ <!-- - `hcompact`: HW implementation of the Ruby `compact` method. However, since there is no nil value in HW, use 0 instead for compacting. Returns a vector signal containing the compaction result. -->
3322
+
3323
+ - `hcount`: HW implementation of the Ruby `count` method. Returns a signal whose bit width matches the size of the enumerator containing the count result.
3324
+
3325
+ <!-- - `hcycle`: HW implementation of the Ruby `cycle` method. -->
3326
+
3327
+ - `hfind`: HW implementation of the Ruby `find` method. Returns a signal containing the found element, or 0 if not found.
3328
+
3329
+ - `hdrop`: HW implementation of the Ruby `drop` method. Returns a vector signal containing the remaining elements.
3330
+
3331
+ <!-- - `hdrop_while`: HW implementation of the Ruby `drop_while` method. Returns a vector signal containing the remaining elements. -->
3332
+
3333
+ - `heach_cons`: HW implementation of the Ruby `each_cons` method.
3334
+
3335
+ - `heach_slice`: HW implementation of the Ruby `each_slice` method.
3336
+
3337
+ - `heach_with_index`: HW implementation of the Ruby `each_with_index` method.
3338
+
3339
+ - `heach_with_object`: HW implementation of the Ruby `each_with_object` method.
3340
+
3341
+ - `hto_a`: HW implementation of the Ruby `to_a` method. Returns a vector signal containing all the elements of the enumerator.
3342
+
3343
+ <!-- - `hselect`: HW implementation of the Ruby `select` method. Returns a vector signal containing the selected elements. -->
3344
+
3345
+ - `hfind_index`: HW implementation of the Ruby `find_index` method. Returns the index of the found element or -1 if not.
3346
+
3347
+ - `hfirst`: HW implementation of the Ruby `first` method. Returns a vector signal containing the first elements.
3348
+
3349
+ - `hinclude?`: HW implementation of the Ruby `include?` method. Returns a single-bit signal. When 0 this value means false and when 1 it means true.
3350
+
3351
+ - `hinject`: HW implementation of the Ruby `inject` method. Return a signal of the type of elements containing the computation result.
3352
+
3353
+ - `hmax`: HW implementation of the Ruby `max` method. Return a vector signal containing the found max values.
3354
+ *Note:* For now only one max value can be returned.
3355
+
3356
+ - `hmax_by`: HW implementation of the Ruby `max_by` method. Return a vector signal containing the found max values.
3357
+ *Note:* For now only one max value can be returned.
3358
+
3359
+ - `hmin`: HW implementation of the Ruby `min` method. Return a vector signal containing the found min values.
3360
+ *Note:* For now only one min value can be returned.
3361
+
3362
+ - `hmin_by`: HW implementation of the Ruby `min_by` method. Return a vector signal containing the found min values.
3363
+ *Note:* For now only one min value can be returned.
3364
+
3365
+ - `hminmax`: HW implementation of the Ruby `minmax` method. Returns a 2-element vector signal containing the resulting min and max values.
3366
+
3367
+ - `hminmax_by`: HW implementation of the Ruby `minmax_by` method. Returns a 2-element vector signal containing the resulting min and max values.
3368
+
3369
+ - `hnone?`: HW implementation of the Ruby `none?` method. Returns a single-bit signal. When 0 this value means false and when 1 it means true.
3370
+
3371
+ - `hone?`: HW implementation of the Ruby `one?` method. Returns a single-bit signal. When 0 this value means false and when 1 it means true.
3372
+
3373
+ <!-- - `hreject`: HW implementation of the Ruby `reject` method. Returns a vector signal containing the remaining elements. -->
3374
+
3375
+ - `hreverse_each`: HW implementation of the Ruby `reverse_each` method.
3376
+ *Note:* This algorithm makes sense inside a `seq` process.
3377
+
3378
+ - `hsort`: HW implementation of the Ruby `sort` method. Returns a vector signal containing the sorted elements.
3379
+ *Note:* If you use a custom comparison (passed as a Ruby block) and the number of elements to sort is not a power of 2, you need to provide as argument the maximum possible value (or minimum in case of decreasing order).
3380
+
3381
+ - `hsort_by`: HW implementation of the Ruby `sort_by` method. Returns a vector signal containing the sorted elements.
3382
+ *Note:* If the number of elements to sort is not a power of 2, you need to provide as argument the maximum possible value (or minimum in case of decreasing order).
3383
+
3384
+ - `hsum`: HW implementation of the Ruby `sum` method. Returns a signal with the type of elements containing the sum result.
3385
+
3386
+ - `htake`: HW implementation of the Ruby `take` method. Returns a vector signal containing the taken elements.
3387
+
3388
+ <!-- - `htake_while`: HW implementation of the Ruby `take_while` method. Returns a vector signal containing the taken elements. -->
3389
+
3390
+ <!-- - `huniq`: HW implementation the Ruby `uniq` method. Returns a vector signal containing the selected elements. -->
3391
+
3392
+
3259
3393
  ## Sequencer (software-like hardware coding):: `std/sequencer.rb`
3260
3394
  <a name="sequencer"></a>
3261
3395
 
@@ -3394,9 +3528,9 @@ end
3394
3528
  ```
3395
3529
 
3396
3530
 
3397
- ### HDLRuby enumerators and enumerable objects: `std/sequencer.rb`
3531
+ ### HDLRuby sequential enumerators and enumerable objects: `std/sequencer.rb`
3398
3532
 
3399
- HDLRuby enumerators are objects for generating iterations within sequencers. They are created using the method `seach` on enumerable objects as presented in the previous section.
3533
+ HDLRuby sequential enumerators are objects for generating iterations within sequencers. They are created using the method `seach` on enumerable objects as presented in the previous section.
3400
3534
 
3401
3535
  The enumerators can be controlled using the following methods:
3402
3536
 
@@ -3850,6 +3984,18 @@ File.open("sequencer_in_ruby.rb","w") do |f|
3850
3984
  end
3851
3985
  ```
3852
3986
 
3987
+ It is also possible to generate C or Python code from the sequencer using the `to_c` and `to_python` methods, respectively. For example, the commands below generate a C file and a Python file from `my_seq`. However, the synchronization commands are not yet supported.
3988
+
3989
+ ```ruby
3990
+ File.open("seqiemcer_in_c.c","w" do |f|
3991
+ f << my_seq.to_c
3992
+ end
3993
+
3994
+ File.open("seqiemcer_in_python.py","w" do |f|
3995
+ f << my_seq.to_python
3996
+ end
3997
+ ```
3998
+
3853
3999
  __Note__: the ruby code for sequencers is compatible with mruby for execution on embedded systems.
3854
4000
 
3855
4001
 
@@ -3990,7 +4136,7 @@ end.()
3990
4136
 
3991
4137
  Both method are functionally equivalent. However, the first is safer as potential errors are detected at the compile stage, but is incompatible with separated code generation and is slow, while the second allows separate code generation, if fast, but is less safe since it is only at the execution stage that the code is checked.
3992
4138
 
3993
- __Note__: Since the string in text is grafted as is into the generated Ruby (or C) code, you cannot directly access the value of a signal. However, you can use to_ruby or to_c to access the underlying raw value, or use value_text to retrieve the value with proper type adjustment in case of overflow or underflow. For example, the following will display the raw value of signal sig0 and the hardware-accurate value of signal sig1:
4139
+ __Note__: Since the string in text is grafted as is into the generated Ruby (or C) code, you cannot directly access the value of a signal. However, you can use to_ruby, to_c or to_python to access the underlying raw value, or use value_text to retrieve the value with proper type adjustment in case of overflow or underflow. For example, the following will display the raw value of signal sig0 and the hardware-accurate value of signal sig1:
3994
4140
 
3995
4141
  ```ruby
3996
4142
  sequencer do
@@ -280,7 +280,8 @@ VALUE rcsim_make_behavior(VALUE mod, VALUE timed) {
280
280
  register_init_behavior(behavior);
281
281
  }
282
282
  behavior->active_time = 0;
283
- behavior->thread = NULL;
283
+ // behavior->thread = NULL;
284
+ behavior->thread = 0;
284
285
  /* Returns the C behavior embedded into a ruby VALUE. */
285
286
  VALUE res;
286
287
  rcsim_to_value(BehaviorS,behavior,res);
@@ -466,7 +467,8 @@ VALUE rcsim_load_c(VALUE mod, VALUE codeV, VALUE libnameV, VALUE funcnameV) {
466
467
  fprintf(stderr,"LoadLibrary failed with error code %ld\n", dwError);
467
468
  exit(-1);
468
469
  }
469
- code->function = GetProcAddress(handle,funcname);
470
+ // code->function = GetProcAddress(handle,funcname);
471
+ code->function = (void (*)(Code))GetProcAddress(handle,funcname);
470
472
  if (code->function == NULL) {
471
473
  fprintf(stderr,"Unable to get function: %s\n",code->name);
472
474
  exit(-1);
@@ -191,7 +191,7 @@ void calc_ref_rangeS(Reference ref, long long* first, long long *last,
191
191
  Cast refc = (Cast)ref;
192
192
  /* Compute the range for the child. */
193
193
  long long cfirst, clast;
194
- calc_ref_rangeS(refc->child,&cfirst,&clast,sig);
194
+ calc_ref_rangeS((Reference)(refc->child),&cfirst,&clast,sig);
195
195
  /* Update first and last using the cast. */
196
196
  /* Both first and last should be equal since the type of the cast sets
197
197
  * the width */
@@ -207,6 +207,76 @@ static void vcd_print_signal_cvalue(SignalI signal) {
207
207
  }
208
208
 
209
209
 
210
+ /** Checks if a statement contains any declaration.
211
+ * @param stmnt the statement to check. */
212
+ static int vcd_statement_has_decl(Statement stmnt) {
213
+ // printf("stmnt kind=%d\n",stmnt->kind);
214
+ switch(stmnt->kind) {
215
+ case TRANSMIT:
216
+ case PRINT:
217
+ /* No declaration. */
218
+ return 0;
219
+ case HIF:
220
+ {
221
+ HIf hif = (HIf)stmnt;
222
+ /* Recruse on the sub statements of the if.*/
223
+ if (vcd_statement_has_decl(hif->yes)) return 1;
224
+ for(int i=0; i<hif->num_noifs; ++i)
225
+ if (vcd_statement_has_decl(hif->nostmnts[i]))
226
+ return 1;
227
+ if (hif->no)
228
+ return vcd_statement_has_decl(hif->no);
229
+ /* No declaration. */
230
+ return 0;
231
+ }
232
+ case HCASE:
233
+ {
234
+ HCase hcase = (HCase)stmnt;
235
+ /* Recruse on the sub statements of the case.*/
236
+ for(int i=0; i<hcase->num_whens; ++i)
237
+ if (vcd_statement_has_decl(hcase->stmnts[i]))
238
+ return 1;
239
+ if (hcase->defolt)
240
+ return vcd_statement_has_decl(hcase->defolt);
241
+ /* No declaration. */
242
+ return 0;
243
+ }
244
+ case TIME_WAIT:
245
+ /* No declaration. */
246
+ return 0;
247
+ case TIME_REPEAT:
248
+ {
249
+ TimeRepeat rep = (TimeRepeat)stmnt;
250
+ /* Recruse on the sub statements of the repeat.*/
251
+ for(long long i=0; i<rep->number; ++i)
252
+ if (vcd_statement_has_decl(rep->statement))
253
+ return 1;
254
+ /* No declaration. */
255
+ return 0;
256
+ }
257
+ case TIME_TERMINATE:
258
+ /* No declaration. */
259
+ return 0;
260
+ case BLOCK:
261
+ {
262
+ Block blk = (Block)stmnt;
263
+ if (blk->num_inners != 0) return 1;
264
+ /* Recruse on the sub statements. */
265
+ for(int i=0; i<blk->num_stmnts; ++i)
266
+ if (vcd_statement_has_decl(blk->stmnts[i]))
267
+ return 1;
268
+ /* No declaration. */
269
+ return 0;
270
+ }
271
+ default:
272
+ perror("Invalid kind for a statement.");
273
+ }
274
+ /* Should not be here though. */
275
+ return 0;
276
+ }
277
+
278
+
279
+
210
280
  /** Prints the hierarchy content of a system type.
211
281
  * @param system the system to print. */
212
282
  static void vcd_print_systemT_content(SystemT system);
@@ -215,13 +285,74 @@ static void vcd_print_systemT_content(SystemT system);
215
285
  * @param scope the scope to print. */
216
286
  static void vcd_print_scope(Scope scope);
217
287
 
288
+ /** Prints the hierarchy of a block.
289
+ * @param block the block to print. */
290
+ static void vcd_print_block(Block block);
291
+
292
+ /** Prints the hierarchy of a statement.
293
+ * @param stmnt the statement to print. */
294
+ static void vcd_print_statement(Statement stmnt) {
295
+ // printf("stmnt kind=%d\n",stmnt->kind);
296
+ switch(stmnt->kind) {
297
+ case TRANSMIT:
298
+ case PRINT:
299
+ /* Nothing to do. */
300
+ break;
301
+ case HIF:
302
+ {
303
+ HIf hif = (HIf)stmnt;
304
+ /* Recruse on the sub statements of the if.*/
305
+ vcd_print_statement(hif->yes);
306
+ for(int i=0; i<hif->num_noifs; ++i)
307
+ vcd_print_statement(hif->nostmnts[i]);
308
+ if (hif->no)
309
+ vcd_print_statement(hif->no);
310
+ break;
311
+ }
312
+ case HCASE:
313
+ {
314
+ HCase hcase = (HCase)stmnt;
315
+ /* Recruse on the sub statements of the case.*/
316
+ for(int i=0; i<hcase->num_whens; ++i)
317
+ vcd_print_statement(hcase->stmnts[i]);
318
+ if (hcase->defolt)
319
+ vcd_print_statement(hcase->defolt);
320
+ break;
321
+ }
322
+ case TIME_WAIT:
323
+ /* Nothing to do. */
324
+ break;
325
+ case TIME_REPEAT:
326
+ {
327
+ TimeRepeat rep = (TimeRepeat)stmnt;
328
+ /* Recruse on the sub statements of the repeat.*/
329
+ for(long long i=0; i<rep->number; ++i)
330
+ vcd_print_statement(rep->statement);
331
+ break;
332
+ }
333
+ case TIME_TERMINATE:
334
+ /* Nothing to do. */
335
+ break;
336
+ case BLOCK:
337
+ {
338
+ /* Block case: there is a specific function for it. */
339
+ vcd_print_block((Block)stmnt);
340
+ break;
341
+ }
342
+ default:
343
+ perror("Invalid kind for a statement.");
344
+ }
345
+ }
346
+
218
347
 
219
348
  /** Prints the hierarchy of a block.
220
349
  * @param block the block to print. */
221
350
  static void vcd_print_block(Block block) {
222
351
  int i;
352
+ // printf("vcd_print_block\n");
223
353
  /* Do not print block with no declaration. */
224
- if (block->num_inners == 0) return;
354
+ // if (block->num_inners == 0) return;
355
+ if (!vcd_statement_has_decl(block)) return;
225
356
 
226
357
  /* Declares the block if named. */
227
358
  vcd_print("$scope module ");
@@ -233,6 +364,11 @@ static void vcd_print_block(Block block) {
233
364
  vcd_print_var(block->inners[i]);
234
365
  }
235
366
 
367
+ /* Recurse on the statements if any. */
368
+ for(i=0; i<block->num_stmnts; ++i) {
369
+ vcd_print_statement(block->stmnts[i]);
370
+ }
371
+
236
372
  /* Close the hierarchy. */
237
373
  vcd_print("$upscope $end\n");
238
374
  }
@@ -258,6 +394,7 @@ static void vcd_print_systemI(SystemI systemI) {
258
394
  * @param scope the scope to print the inside. */
259
395
  static void vcd_print_scope_content(Scope scope) {
260
396
  int i;
397
+ // printf("vcd_print_scope_content\n");
261
398
 
262
399
  /* Declare the inners of the systems. */
263
400
  for(i=0; i<scope->num_inners; ++i) {
@@ -0,0 +1,26 @@
1
+ # Sample for testing an invalid function: should generate an error.
2
+
3
+
4
+ hdef :func do |val|
5
+ [8].inner :res
6
+ hif (val == 1) { res <= _h60 }
7
+ helse { res <= _h70 }
8
+ end
9
+
10
+
11
+ system :with_func do
12
+ [8].inner :val,:res
13
+
14
+ res <= func(val)
15
+
16
+ timed do
17
+ val <= 0
18
+ !10.ns
19
+ val <= 1
20
+ !10.ns
21
+ val <= 2
22
+ !10.ns
23
+ val <= 3
24
+ !10.ns
25
+ end
26
+ end