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 +4 -4
- data/README.md +149 -3
- data/ext/hruby_sim/hruby_rcsim_build.c +4 -2
- data/ext/hruby_sim/hruby_sim_tree_calc.c +1 -1
- data/ext/hruby_sim/hruby_sim_vcd.c +138 -1
- data/lib/HDLRuby/hdr_samples/invalid_function.rb +26 -0
- data/lib/HDLRuby/hdr_samples/with_henumerable.rb +390 -0
- data/lib/HDLRuby/hdr_samples/with_val_control.rb +107 -0
- data/lib/HDLRuby/hdrcc.rb +15 -4
- data/lib/HDLRuby/hruby_high.rb +218 -37
- data/lib/HDLRuby/hruby_rcsim.rb +1 -1
- data/lib/HDLRuby/std/hruby_enum.rb +1167 -0
- data/lib/HDLRuby/std/sequencer.rb +3 -2
- data/lib/HDLRuby/std/sequencer_sw.rb +305 -4
- data/lib/HDLRuby/std/std.rb +1 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3ecb1e50d09ad4ec7aa0809f93da534ce0672c30240aa9405124a075d29a015
|
4
|
+
data.tar.gz: 3b939a8ad0eeef795473657775a83c265597fa13939dae1c91bff685ab6024b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|