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.
- checksums.yaml +4 -4
- data/README.html +4121 -4648
- data/README.md +117 -105
- data/ext/hruby_sim/hruby_rcsim_build.c +2 -0
- data/ext/hruby_sim/hruby_sim.h +6 -0
- data/ext/hruby_sim/hruby_sim_calc.c +67 -0
- data/lib/HDLRuby/hdr_samples/with_henumerable.rb +281 -258
- data/lib/HDLRuby/hdr_samples/with_to_svg.rb +37 -0
- data/lib/HDLRuby/hdr_samples/with_unary_reduction.rb +23 -0
- data/lib/HDLRuby/hdr_samples/with_values.rb +4 -0
- data/lib/HDLRuby/hdrcc.rb +3 -0
- data/lib/HDLRuby/hruby_bstr.rb +2 -1
- data/lib/HDLRuby/hruby_high.rb +35 -7
- data/lib/HDLRuby/hruby_low.rb +52 -87
- data/lib/HDLRuby/hruby_low_split_signals.rb +213 -0
- data/lib/HDLRuby/hruby_types.rb +6 -2
- data/lib/HDLRuby/hruby_viz.rb +359 -166
- data/lib/HDLRuby/std/hruby_enum.rb +104 -28
- data/lib/HDLRuby/std/sequencer.rb +17 -3
- data/lib/HDLRuby/verilog_hruby.rb +70 -28
- data/lib/HDLRuby/verilog_parser.rb +38 -18
- data/lib/HDLRuby/version.rb +1 -1
- metadata +5 -2
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
|
-
|
|
12
|
+
* [Introduction](#introduction)
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
* [How HDLRuby Works](#how-hdlruby-works)
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
* [Naming rules](#naming-rules)
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
* [Systems and Signals](#systems-and-signals)
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
* [Events](#events)
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
* [Statements](#statements)
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
* [Types](#types)
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
* [Expressions](#expressions)
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
* [Functions](#functions)
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
* [Software code](#software-code)
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
* [Time](#time)
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
* [High-Level Programming Features](#high-level-programming-features)
|
|
35
35
|
|
|
36
|
-
|
|
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
|
-
|
|
43
|
+
* [Clocks](#clocks)
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
* [Decoder](#decoder)
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
* [FSM](#fsm)
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
* [Parallel Enumerators](#parallel-enumerators)
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
* [Sequencer (Software-like Hardware Coding)](#sequencer-software-like-hardware-coding)
|
|
52
52
|
|
|
53
|
-
|
|
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
|
|
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
|
-
|
|
99
|
+
* Rewrote the beginning of the [HDLRuby Programming Guide](#hdlruby-programming-guide).
|
|
96
100
|
|
|
97
|
-
|
|
101
|
+
* Updated the documentation for interactive mode.
|
|
98
102
|
|
|
99
|
-
|
|
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
|
|
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](#
|
|
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 [
|
|
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
|
|
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
|
-
|
|
239
|
-
|
|
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
|
-
|
|
423
|
-
|
|
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](
|
|
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
|
-
|
|
718
|
-
You can define a new system that inherits from the existing `dff`:
|
|
722
|
+
1. Inheriting from a Module.
|
|
719
723
|
|
|
720
|
-
|
|
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
|
-
|
|
726
|
+
```ruby
|
|
727
|
+
system :dff_full, dff do
|
|
728
|
+
output :qb
|
|
729
|
+
qb <= ~q
|
|
730
|
+
end
|
|
731
|
+
```
|
|
728
732
|
|
|
729
|
-
|
|
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
|
-
|
|
733
|
-
dff.open do
|
|
734
|
-
output :qb
|
|
735
|
-
qb <= ~q
|
|
736
|
-
end
|
|
737
|
-
```
|
|
735
|
+
2. Reopening a Module.
|
|
738
736
|
|
|
739
|
-
|
|
737
|
+
You can modify the original `dff` module after its declaration using the open method:
|
|
740
738
|
|
|
741
|
-
|
|
742
|
-
|
|
739
|
+
```ruby
|
|
740
|
+
dff.open do
|
|
741
|
+
output :qb
|
|
742
|
+
qb <= ~q
|
|
743
|
+
end
|
|
744
|
+
```
|
|
743
745
|
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1318
|
+
* Ruby integers (e.g., `42`) are treated as 64-bit HDLRuby values.
|
|
1311
1319
|
|
|
1312
|
-
|
|
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
|
-
|
|
1593
|
+
* `helse seq` ensures that the block of the hardware `else` is in blocking assignment mode.
|
|
1586
1594
|
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2480
|
+
* `:ruby` -- for programs written in Ruby.
|
|
2473
2481
|
|
|
2474
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2490
|
+
* `inport <port_name: signal>` -- Declares input ports that can be read by the software.
|
|
2483
2491
|
|
|
2484
|
-
|
|
2492
|
+
* `outport <port_name: signal>` -- Declares output ports that the software can write to.
|
|
2485
2493
|
|
|
2486
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3380
|
+
* Within a module: interpreted as a static connection.
|
|
3373
3381
|
|
|
3374
|
-
|
|
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
|
-
|
|
3409
|
+
* `sys0` works correctly.
|
|
3402
3410
|
|
|
3403
|
-
|
|
3411
|
+
* `sys1` raises an error due to redeclaration of `in0`.
|
|
3404
3412
|
|
|
3405
|
-
|
|
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
|
-
|
|
3419
|
+
* Variadic arguments (`*args`)
|
|
3412
3420
|
|
|
3413
|
-
|
|
3421
|
+
* Named (keyword) arguments
|
|
3414
3422
|
|
|
3415
|
-
|
|
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
|
-
|
|
3815
|
+
* If name is `:sync`, the reset is forced to be synchronous.
|
|
3808
3816
|
|
|
3809
|
-
|
|
3817
|
+
* If name is `:async`, the reset is forced to be asynchronous.
|
|
3810
3818
|
|
|
3811
|
-
|
|
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
|
|
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
|
-
|
|
4909
|
+
* Calling it again using the call operator (`my_seq.()`), or
|
|
4898
4910
|
|
|
4899
|
-
|
|
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);
|
data/ext/hruby_sim/hruby_sim.h
CHANGED
|
@@ -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
|