HDLRuby 3.9.0 → 3.9.3

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.
data/README.md CHANGED
@@ -9,48 +9,48 @@ If you want to learn how to describe a circuit with HDLRuby, please jump to the
9
9
 
10
10
  * [HDLRuby Programming Guide](#hdlruby-programming-guide)
11
11
 
12
- - [Introduction](#introduction)
12
+ * [Introduction](#introduction)
13
13
 
14
- - [How HDLRuby Works](#how-hdlruby-works)
14
+ * [How HDLRuby Works](#how-hdlruby-works)
15
15
 
16
- - [Naming rules](#naming-rules)
16
+ * [Naming rules](#naming-rules)
17
17
 
18
- - [Systems and Signals](#systems-and-signals)
18
+ * [Systems and Signals](#systems-and-signals)
19
19
 
20
- - [Events](#events)
20
+ * [Events](#events)
21
21
 
22
- - [Statements](#statements)
22
+ * [Statements](#statements)
23
23
 
24
- - [Types](#types)
24
+ * [Types](#types)
25
25
 
26
- - [Expressions](#expressions)
26
+ * [Expressions](#expressions)
27
27
 
28
- - [Functions](#functions)
28
+ * [Functions](#functions)
29
29
 
30
- - [Software code](#software-code)
30
+ * [Software code](#software-code)
31
31
 
32
- - [Time](#time)
32
+ * [Time](#time)
33
33
 
34
- - [High-Level Programming Features](#high-level-programming-features)
34
+ * [High-Level Programming Features](#high-level-programming-features)
35
35
 
36
- - [Extending HDLRuby](#extending-hdlruby)
36
+ * [Extending HDLRuby](#extending-hdlruby)
37
37
 
38
38
  Many of HDLRuby's features are available through its standard libraries.
39
39
  We strongly recommend consulting the corresponding section:
40
40
 
41
41
  * [Standard Libraries](#standard-libraries)
42
42
 
43
- - [Clocks](#clocks)
43
+ * [Clocks](#clocks)
44
44
 
45
- - [Decoder](#decoder)
45
+ * [Decoder](#decoder)
46
46
 
47
- - [FSM](#fsm)
47
+ * [FSM](#fsm)
48
48
 
49
- - [Parallel Enumerators](#parallel-enumerator)
49
+ * [Parallel Enumerators](#parallel-enumerators)
50
50
 
51
- - [Sequencer (Software-like Hardware Coding)](#sequencer-software-like-hardware coding)
51
+ * [Sequencer (Software-like Hardware Coding)](#sequencer-software-like-hardware-coding)
52
52
 
53
- - [Fixed-Point](#fixed-point)
53
+ * [Fixed-Point](#fixed-point)
54
54
 
55
55
  Samples are also available: [Sample HDLRuby descriptions](#sample-hdlruby-descriptions)
56
56
 
@@ -71,7 +71,11 @@ hdrcc --get-tuto
71
71
 
72
72
  __What's New__
73
73
 
74
- For HDLRuby version 3.9.0:
74
+ For HDKRuby version 3.9.2:
75
+
76
+ * Added the `hbreak` command for exiting parallel enumerator loops.
77
+
78
+ For HDLRuby version 3.9.0/3.9.1:
75
79
 
76
80
  * Added the parallel enumerators to the software sequencers.
77
81
 
@@ -92,11 +96,11 @@ For HDLRuby version 3.8.3:
92
96
 
93
97
  * Updated the documentation:
94
98
 
95
- - Rewrote the beginning of the [HDLRuby Programming Guide](#hdlruby-programming-guide).
99
+ * Rewrote the beginning of the [HDLRuby Programming Guide](#hdlruby-programming-guide).
96
100
 
97
- - Updated the documentation for interactive mode.
101
+ * Updated the documentation for interactive mode.
98
102
 
99
- - Updated the [High-Level Programming Features](#high-level-programming-features) chapter.
103
+ * Updated the [High-Level Programming Features](#high-level-programming-features) chapter.
100
104
 
101
105
  For HDLRuby version 3.8.0:
102
106
 
@@ -111,7 +115,7 @@ For HDLRuby version 3.7.9:
111
115
 
112
116
  * Added Python code generation from software sequencers.
113
117
 
114
- * Added [Parallel Enumerators](#parallel-enumerators-stdhruby_enumrb).
118
+ * Added [Parallel Enumerators](#parallel-enumerators).
115
119
 
116
120
  For HDLRuby versions 3.7.7/3.7.8:
117
121
 
@@ -170,7 +174,7 @@ For HDLRuby version 3.4.0:
170
174
 
171
175
  * Added [v2hdr](#converting-verilog-hdl-to-hdlruby), a standalone tool for converting Verilog HDL files to HDLRuby (experimental).
172
176
 
173
- * Added a HDLRuby command for [loading a Verilog HDL file from a HDLRuby description](#loading-verilog-hdl-from-hdlruby).
177
+ * Added a HDLRuby command for [loading a Verilog HDL file from a HDLRuby description](#converting-verilog-hdl-to-hdlruby).
174
178
 
175
179
 
176
180
  For HDLRuby version 3.3.0:
@@ -197,7 +201,7 @@ For HDLRuby version 3.2.0:
197
201
 
198
202
  For HDLRuby version 3.1.0:
199
203
 
200
- * Added [Functions for sequencers](#sequencer-specific-function-std-sequencer_func-rb), including support for recursion.
204
+ * Added [functions for sequencers](#sequencer-specific-functions), including support for recursion.
201
205
 
202
206
  * Replaced the `function` keyword with `hdef` for consistency with sequencer functions (`sdef`).
203
207
 
@@ -211,7 +215,7 @@ For HDLRuby version 3.0.0:
211
215
 
212
216
  * Intruduced this changelog section.
213
217
 
214
- * Added [Sequencers](#sequencer-software-like-hardware-coding-stdsequencerrb) for software-like hardware design.
218
+ * Added [Sequencers](#sequencer-software-like-hardware-coding) for software-like hardware design.
215
219
 
216
220
  * Added a [tutorial](tuto/tutorial_sw.md) for software developers.
217
221
 
@@ -235,8 +239,9 @@ git clone https://github.com/civol/HDLRuby.git
235
239
 
236
240
  __Warning__:
237
241
 
238
- - HDLRuby is still under active development, and the API may change before a stable release.
239
- - It is highly recommended that users have a basic understanding of both the Ruby programming language and hardware description languages before using HDLRuby.
242
+ * HDLRuby is still under active development, and the API may change before a stable release.
243
+
244
+ * It is highly recommended that users have a basic understanding of both the Ruby programming language and hardware description languages before using HDLRuby.
240
245
 
241
246
 
242
247
  # Compiling HDLRuby Descriptions
@@ -419,8 +424,8 @@ Another key feature of HDLRuby is its native support for all features of the Rub
419
424
 
420
425
  __Notes__:
421
426
 
422
- - It is possible to extend HDLRuby to support hardware descriptions at a higher level of abstraction than RTL. See [Extending HDLRuby](#extending-hdlruby) for more details.
423
- - Throughout this guide, HDLRuby constructs are often compared to their Verilog HDL or VHDL equivalents to aid understanding.
427
+ * It is possible to extend HDLRuby to support hardware descriptions at a higher level of abstraction than RTL. See [Extending HDLRuby](#extending-hdlruby) for more details.
428
+ * Throughout this guide, HDLRuby constructs are often compared to their Verilog HDL or VHDL equivalents to aid understanding.
424
429
 
425
430
  ## Introduction
426
431
 
@@ -467,7 +472,7 @@ These include:
467
472
 
468
473
  * `mux`, an expression-level construct for multiplexers, which supports multiple inputs, unlike the ?: ternary operator in Verilog, which only handles two
469
474
 
470
- __Note__: These statements are also called "parallel conditionals" in HDLRuby, to contrast with the ones used in the `sequencer` constructs (see [Sequencer](##sequencer-software-like-Hardware-coding)).
475
+ __Note__: These statements are also called "parallel conditionals" in HDLRuby, to contrast with the ones used in the `sequencer` constructs (see [Sequencer](#sequencer-software-like-Hardware-coding)).
471
476
 
472
477
  For example, we can upgrade the 8-bit adder to an adder-subtractor:
473
478
 
@@ -714,45 +719,48 @@ Fourth, HDLRuby allows you to extend modules and instances after their declarati
714
719
 
715
720
  Let us say you want to extend an existing `dff` module to include an inverted output (`qb`). There are three ways to do this:
716
721
 
717
- 1. Inheriting from a Module.
718
- You can define a new system that inherits from the existing `dff`:
722
+ 1. Inheriting from a Module.
719
723
 
720
- ```ruby
721
- system :dff_full, dff do
722
- output :qb
723
- qb <= ~q
724
- end
725
- ```
724
+ You can define a new system that inherits from the existing `dff`:
726
725
 
727
- This creates a new module `dff_full` that includes all the functionality of `dff`, with the additional inverted output.
726
+ ```ruby
727
+ system :dff_full, dff do
728
+ output :qb
729
+ qb <= ~q
730
+ end
731
+ ```
728
732
 
729
- 2. Reopening a Module.
730
- You can modify the original `dff` module after its declaration using the open method:
733
+ This creates a new module `dff_full` that includes all the functionality of `dff`, with the additional inverted output.
731
734
 
732
- ```ruby
733
- dff.open do
734
- output :qb
735
- qb <= ~q
736
- end
737
- ```
735
+ 2. Reopening a Module.
738
736
 
739
- This approach modifies `dff` itself, and the added behavior (`qb <= ~q`) will apply to all future instances of `dff`.
737
+ You can modify the original `dff` module after its declaration using the open method:
740
738
 
741
- 3. Reopening a Specific Instance.
742
- You can also modify a single instance of a module without affecting the others:
739
+ ```ruby
740
+ dff.open do
741
+ output :qb
742
+ qb <= ~q
743
+ end
744
+ ```
743
745
 
744
- ```ruby
745
- # Declare dff0 as an instance of dff
746
- dff :dff0
747
-
748
- # Modify it
749
- dff0.open do
750
- output :qb
751
- qb <= ~q
752
- end
753
- ```
746
+ This approach modifies `dff` itself, and the added behavior (`qb <= ~q`) will apply to all future instances of `dff`.
747
+
748
+ 3. Reopening a Specific Instance.
754
749
 
755
- In this case, only `dff0` will have the qb inverted output. Other instances of `dff` remain unchanged.
750
+ You can also modify a single instance of a module without affecting the others:
751
+
752
+ ```ruby
753
+ # Declare dff0 as an instance of dff
754
+ dff :dff0
755
+
756
+ # Modify it
757
+ dff0.open do
758
+ output :qb
759
+ qb <= ~q
760
+ end
761
+ ```
762
+
763
+ In this case, only `dff0` will have the qb inverted output. Other instances of `dff` remain unchanged.
756
764
 
757
765
  In summary, HDLRuby supports:
758
766
 
@@ -1095,19 +1103,19 @@ system(:box) {}
1095
1103
 
1096
1104
  __Notes__:
1097
1105
 
1098
- - Since this is Ruby code, the block can also be written using `do...end` syntax. In that case, parentheses around the name are optional:
1106
+ * Since this is Ruby code, the block can also be written using `do...end` syntax. In that case, parentheses around the name are optional:
1099
1107
 
1100
1108
 
1101
- ```ruby
1102
- system :box do
1103
- end
1104
- ```
1109
+ ```ruby
1110
+ system :box do
1111
+ end
1112
+ ```
1105
1113
 
1106
- - Although HDLRuby internally stores names as Ruby symbols, you can also use strings. For example, the following is equally valid:
1114
+ * Although HDLRuby internally stores names as Ruby symbols, you can also use strings. For example, the following is equally valid:
1107
1115
 
1108
- ```ruby
1109
- system("box") {}
1110
- ```
1116
+ ```ruby
1117
+ system("box") {}
1118
+ ```
1111
1119
 
1112
1120
  ### Declaring a system with an interface
1113
1121
 
@@ -1307,9 +1315,9 @@ __Notes__:
1307
1315
 
1308
1316
  * By default:
1309
1317
 
1310
- - Ruby integers (e.g., `42`) are treated as 64-bit HDLRuby values.
1318
+ * Ruby integers (e.g., `42`) are treated as 64-bit HDLRuby values.
1311
1319
 
1312
- - HDLRuby literals prefixed with `_` (e.g., `_b1010`, `_h0F`) have a bit-width corresponding to their representation.
1320
+ * HDLRuby literals prefixed with `_` (e.g., `_b1010`, `_h0F`) have a bit-width corresponding to their representation.
1313
1321
 
1314
1322
  * When initializing ROM or arrays of values, make sure that the bit-width of the values matches the declared type -- otherwise, misalignments or synthesis issues may occur.
1315
1323
 
@@ -1582,17 +1590,17 @@ end
1582
1590
 
1583
1591
  __Notes__:
1584
1592
 
1585
- - `helse seq` ensures that the block of the hardware `else` is in blocking assignment mode.
1593
+ * `helse seq` ensures that the block of the hardware `else` is in blocking assignment mode.
1586
1594
 
1587
- - `hif(rst)` could also have been set to blocking assignment mode as follows:
1588
-
1589
- ```ruby
1590
- hif rst, seq do
1591
- reg <= 0
1592
- end
1593
- ```
1595
+ * `hif(rst)` could also have been set to blocking assignment mode as follows:
1596
+
1597
+ ```ruby
1598
+ hif rst, seq do
1599
+ reg <= 0
1600
+ end
1601
+ ```
1594
1602
 
1595
- - non-blocking mode can be set the same way using `par`.
1603
+ * Non-blocking mode can be set the same way using `par`.
1596
1604
 
1597
1605
 
1598
1606
  ### Extra Features for the Description of Processes
@@ -2469,21 +2477,21 @@ In this declaration:
2469
2477
 
2470
2478
  * `programming_language` is a symbol indicating the language used for the software. Currently supported options are:
2471
2479
 
2472
- - `:ruby` -- for programs written in Ruby.
2480
+ * `:ruby` -- for programs written in Ruby.
2473
2481
 
2474
- - `:c` -- for programs written in C. (In fact, any language that can be compiled into a shared library linkable with C is supported.)
2482
+ * `:c` -- for programs written in C. (In fact, any language that can be compiled into a shared library linkable with C is supported.)
2475
2483
 
2476
2484
  * `function_name` is the name of the software function that is executed when an activation event occurs. Only one such function can be specified per program, but multiple programs can be declared within the same module.
2477
2485
 
2478
2486
  * `location of the software files and description of its interface` may include the following declarations:
2479
2487
 
2480
- - `actport <list of events>` -- Declares the events that activate the program (i.e., trigger execution of the program’s start function).
2488
+ * `actport <list of events>` -- Declares the events that activate the program (i.e., trigger execution of the program’s start function).
2481
2489
 
2482
- - `inport <port_name: signal>` -- Declares input ports that can be read by the software.
2490
+ * `inport <port_name: signal>` -- Declares input ports that can be read by the software.
2483
2491
 
2484
- - `outport <port_name: signal>` -- Declares output ports that the software can write to.
2492
+ * `outport <port_name: signal>` -- Declares output ports that the software can write to.
2485
2493
 
2486
- - `code <list_of_filenames>` -- Specifies the software source file(s).
2494
+ * `code <list_of_filenames>` -- Specifies the software source file(s).
2487
2495
 
2488
2496
  __Example:__
2489
2497
 
@@ -2508,9 +2516,9 @@ end
2508
2516
 
2509
2517
  __Notes:__
2510
2518
 
2511
- * The bit width of an input or output port matches that of the signal it is connected to. From the software perspective, however, all port values are converted to the C type `long long`.
2519
+ * The bit width of an input or output port matches that of the signal it is connected to. From the software perspective, however, all port values are converted to the C type `long long`.
2512
2520
 
2513
- * If the language is Ruby, the `code` section can use a Ruby `Proc` objecct in place of a file name.
2521
+ * If the language is Ruby, the `code` section can use a Ruby `Proc` objecct in place of a file name.
2514
2522
 
2515
2523
 
2516
2524
 
@@ -3369,9 +3377,9 @@ __Warnings__:
3369
3377
 
3370
3378
  * In the example above, the semantics of some_arrow change depending on the context in which it is called:
3371
3379
 
3372
- - Within a module: interpreted as a static connection.
3380
+ * Within a module: interpreted as a static connection.
3373
3381
 
3374
- - Within a process: interpreted as a behavioral assignment.
3382
+ * Within a process: interpreted as a behavioral assignment.
3375
3383
 
3376
3384
  * Using Ruby methods to describe hardware can lead to fragile or incorrect code if not used carefully. For example, consider the following:1
3377
3385
 
@@ -3398,21 +3406,21 @@ __Warnings__:
3398
3406
 
3399
3407
  In this case:
3400
3408
 
3401
- - `sys0` works correctly.
3409
+ * `sys0` works correctly.
3402
3410
 
3403
- - `sys1` raises an error due to redeclaration of `in0`.
3411
+ * `sys1` raises an error due to redeclaration of `in0`.
3404
3412
 
3405
- - `sys2` raises an error because `input` declarations are not allowed inside a process.
3413
+ * `sys2` raises an error because `input` declarations are not allowed inside a process.
3406
3414
 
3407
3415
  __Using Ruby Method Features__
3408
3416
 
3409
3417
  Ruby methods in HDLRuby support all standard Ruby features, including:
3410
3418
 
3411
- * Variadic arguments (`*args`)
3419
+ * Variadic arguments (`*args`)
3412
3420
 
3413
- * Named (keyword) arguments
3421
+ * Named (keyword) arguments
3414
3422
 
3415
- * Block arguments (`&block`)
3423
+ * Block arguments (`&block`)
3416
3424
 
3417
3425
  For example, the following method connects a single driver signal to multiple targets:
3418
3426
 
@@ -3804,11 +3812,11 @@ The available state kinds are:
3804
3812
 
3805
3813
  * `reset`: The state entered when the FSM is reset.
3806
3814
 
3807
- - If name is `:sync`, the reset is forced to be synchronous.
3815
+ * If name is `:sync`, the reset is forced to be synchronous.
3808
3816
 
3809
- - If name is `:async`, the reset is forced to be asynchronous.
3817
+ * If name is `:async`, the reset is forced to be asynchronous.
3810
3818
 
3811
- - If name is omitted, the mode defaults to that of the FSM.
3819
+ * If name is omitted, the mode defaults to that of the FSM.
3812
3820
 
3813
3821
  * `state`: A regular state that follows the FSM’s default mode.
3814
3822
 
@@ -3977,6 +3985,10 @@ Parallel enumerators provide several control methods:
3977
3985
 
3978
3986
  * `+`: Concatenates two enumerators.
3979
3987
 
3988
+ Additionaly, it is possible to exit an enumeration loop using the following command:
3989
+
3990
+ * `hbreak`: Exits the current enumeration loop.
3991
+
3980
3992
  __Hardware Implementations of Enumerable Methods__
3981
3993
 
3982
3994
  Using parallel enumerators, HDLRuby provides hardware implementations of many Ruby Enumerable methods. These are available for any enumerable object and can be used inside or outside processes.
@@ -4149,7 +4161,7 @@ __Using Enumerators in Sequences__
4149
4161
 
4150
4162
  Within sequencer blocks, HDLRuby provides enumerator methods similar to Ruby’s `each`. These include:
4151
4163
 
4152
- * `<object>.seach`: `object` can be any Ruby enumerable or HDLRuby signal. If a block is given, it behaves like sfor; otherwise, it returns an HDLRuby enumerator (see [enumerator](#hdlruby-enumerators-and-enumerable-objects-stdsequencerrb) for details).
4164
+ * `<object>.seach`: `object` can be any Ruby enumerable or HDLRuby signal. If a block is given, it behaves like sfor; otherwise, it returns an HDLRuby enumerator (see [enumerator](#hdlruby-enumerators-and-enumerable-objects) for details).
4153
4165
 
4154
4166
  * `<object>.stimes`: Can be used on integers and is equivalent to calling seach on the range `0..object-1`.
4155
4167
 
@@ -4894,9 +4906,9 @@ When a `sync` command is encountered during execution:
4894
4906
 
4895
4907
  * The paused sequencer can later be resumed by either:
4896
4908
 
4897
- - Calling it again using the call operator (`my_seq.()`), or
4909
+ * Calling it again using the call operator (`my_seq.()`), or
4898
4910
 
4899
- - Setting its associated start signal to `1`.
4911
+ * Setting its associated start signal to `1`.
4900
4912
 
4901
4913
  __Example: Pausing and Resuming a Sequencer__
4902
4914
 
@@ -760,6 +760,8 @@ VALUE rcsim_make_unary(VALUE mod, VALUE type, VALUE operator, VALUE child) {
760
760
  switch(sym_to_char(operator)) {
761
761
  case (unsigned char)'~': unary->oper = not_value; break;
762
762
  case (unsigned char)('-'+'@'*2): unary->oper = neg_value; break;
763
+ case (unsigned char)'|': unary->oper = reduce_or_value; break;
764
+ case (unsigned char)'&': unary->oper = reduce_and_value; break;
763
765
  default: perror("Invalid operator for unary.");
764
766
  }
765
767
  value_to_rcsim(ExpressionS,child,unary->child);
@@ -252,6 +252,12 @@ extern Value not_value(Value src, Value dst);
252
252
  * @return dst */
253
253
  extern Value reduce_or_value(Value src, Value dst);
254
254
 
255
+ /** Compute the and of the bits a a value.
256
+ * @param src the source value
257
+ * @param dst the destination value
258
+ * @return dst */
259
+ extern Value reduce_and_value(Value src, Value dst);
260
+
255
261
  /** Computes the AND of two values.
256
262
  * @param src0 the first source value of the and
257
263
  * @param src1 the second source value of the and
@@ -1348,6 +1348,44 @@ Value reduce_or_value_bitstring(Value src, Value dst) {
1348
1348
  return dst;
1349
1349
  }
1350
1350
 
1351
+ /** Compute the and of the bits a bitstring value.
1352
+ * @param src the source value
1353
+ * @param dst the destination value
1354
+ * @return dst */
1355
+ Value reduce_and_value_bitstring(Value src, Value dst) {
1356
+ /* Compute the width of the result in bits. */
1357
+ unsigned long long width = type_width(src->type);
1358
+
1359
+ /* Update the destination capacity if required. */
1360
+ resize_value(dst,width);
1361
+ /* Set the type and size of the destination from the type of the source.*/
1362
+ dst->type = src->type;
1363
+ dst->numeric = 0;
1364
+
1365
+ /* Get access to the source and destination data. */
1366
+ char* src_data = src->data_str;
1367
+ char* dst_data = dst->data_str;
1368
+
1369
+ /* Performs the reduce or. */
1370
+ unsigned long long count;
1371
+ char res = 0;
1372
+ for(count = 0; count < width; ++count) {
1373
+ /* Performs the reduce and. */
1374
+ char d = src_data[count] - '0'; /* Get and convert to bit. */
1375
+ if ((d == (d&1)) && (res != 'x'-'0')) { /* d is defined. */
1376
+ res &= d;
1377
+ } else {
1378
+ /* res is undefined. */
1379
+ res = 'x' - '0';
1380
+ }
1381
+ /* Apart for the first bit, there are only 0, still we are in
1382
+ * the loop, set it. */
1383
+ dst_data[count] = '0';
1384
+ }
1385
+ dst_data[0] = res + '0';
1386
+ /* Return the destination. */
1387
+ return dst;
1388
+ }
1351
1389
 
1352
1390
  /** Computes the and of two bitstring values.
1353
1391
  * @param src0 the first source value of the and
@@ -2280,6 +2318,21 @@ Value reduce_or_value_numeric(Value src, Value dst) {
2280
2318
  return dst;
2281
2319
  }
2282
2320
 
2321
+ /** Compute the and of the bits a numeric value.
2322
+ * @param src the source value
2323
+ * @param dst the destination value
2324
+ * @return dst */
2325
+ Value reduce_and_value_numeric(Value src, Value dst) {
2326
+ /* Sets state of the destination using the first source. */
2327
+ dst->type = src->type;
2328
+ dst->numeric = 1;
2329
+
2330
+ /* Perform the reduce and. */
2331
+ unsigned long long mask = ~(-1LL << type_width(src->type));
2332
+ dst->data_int = fix_numeric_type(dst->type, (~src->data_int & mask) == 0);
2333
+ return dst;
2334
+ }
2335
+
2283
2336
 
2284
2337
  /** Computes the AND of two numeric values.
2285
2338
  * @param src0 the first source value of the addition
@@ -3061,6 +3114,20 @@ Value reduce_or_value(Value src, Value dst) {
3061
3114
  }
3062
3115
  }
3063
3116
 
3117
+ /** Compute the and of the bits a value.
3118
+ * @param src the source value
3119
+ * @param dst the destination value
3120
+ * @return dst */
3121
+ Value reduce_and_value(Value src, Value dst) {
3122
+ if (src->numeric) {
3123
+ /* The source is numeric. */
3124
+ return reduce_and_value_numeric(src,dst);
3125
+ } else {
3126
+ /* The source cannot be numeric, compute bitsitrings. */
3127
+ return reduce_and_value_bitstring(src,dst);
3128
+ }
3129
+ }
3130
+
3064
3131
 
3065
3132
  /** Computes the AND of two general values.
3066
3133
  * @param src0 the first source value of the addition