HDLRuby 3.7.7 → 3.7.9
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 +144 -3
- data/ext/hruby_sim/hruby_sim_calc.c +282 -72
- data/lib/HDLRuby/hdr_samples/comparison_bench.rb +34 -0
- data/lib/HDLRuby/hdr_samples/with_henumerable.rb +366 -0
- data/lib/HDLRuby/std/hruby_enum.rb +924 -0
- data/lib/HDLRuby/std/sequencer.rb +1 -1
- data/lib/HDLRuby/std/sequencer_sw.rb +314 -11
- data/lib/HDLRuby/std/std.rb +1 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5cd33c7551f3da873475ca05e7047b40cd83abf4016e97fcdcbf266dca32b9b2
|
4
|
+
data.tar.gz: 4bce7700302da9f025b7bea65102973375746d6f767013a0b4db9259b7aea464
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9914adec792666008ce4a122d9014ede48b27c7c649c26b969d9eddf34e08a742382feda2925991522f0a9d632763d3d65df444ac48ad3ac5927bc0f44750ed7
|
7
|
+
data.tar.gz: 297426eacd2fe788c6fb2f7ea239106a3c4eab1ea48e1506f36058ec259479e49a9c2d7aa746b090fe16f147e46568c6cb101b8351bb70ec3b226ccdbf965069
|
data/README.md
CHANGED
@@ -17,6 +17,16 @@ hdrcc --get-tuto
|
|
17
17
|
|
18
18
|
__What's new_
|
19
19
|
|
20
|
+
For HDLRuby version 3.7.9:
|
21
|
+
|
22
|
+
* Added Python code generation from the software sequencers.
|
23
|
+
|
24
|
+
* Added [parallel enumerators](#parallel-enumerators-stdhruby_enumrb).
|
25
|
+
|
26
|
+
For HDLRuby versions 3.7.7/3.7.8:
|
27
|
+
|
28
|
+
* Various fixes regqrding the software sequencers.
|
29
|
+
|
20
30
|
For HDLRuby version 3.7.6:
|
21
31
|
|
22
32
|
* Added initial value to signals for the software sequencers.
|
@@ -3252,6 +3262,125 @@ fsm(clk.posedge,rst,:static)
|
|
3252
3262
|
end
|
3253
3263
|
```
|
3254
3264
|
|
3265
|
+
|
3266
|
+
## Parallel Enumerators:: `std/hruby_enum.rb`
|
3267
|
+
<a name="enumertor"></a>
|
3268
|
+
|
3269
|
+
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.
|
3270
|
+
|
3271
|
+
Parallel enumerable objects include, arrays of signals and ranges.
|
3272
|
+
A parallel enumerable object can also be generated from an integer values using one of the following method:
|
3273
|
+
|
3274
|
+
|
3275
|
+
- `<integer>.htimes`: is equivalent to the range `0..<integer-1>`.
|
3276
|
+
|
3277
|
+
- `<integer>.supto(<last>)`: is equivalent to the range `<integer>..<last>`.
|
3278
|
+
|
3279
|
+
- `<integer>.sdownto(<last>)`: is equivalent to the range `<last>..<integer>`.
|
3280
|
+
|
3281
|
+
The parallel enumerators can be controlled using the following methods:
|
3282
|
+
|
3283
|
+
- `hsize`: returns the number of elements the enumerator can access.
|
3284
|
+
|
3285
|
+
- `htype`: returns the type of the elements accessed by the enumerator.
|
3286
|
+
|
3287
|
+
- `heach`: returns the current enumerator. If a block is given, it performs the iteration instead of returning an enumerator.
|
3288
|
+
|
3289
|
+
- `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.
|
3290
|
+
|
3291
|
+
- `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.
|
3292
|
+
|
3293
|
+
- `with_index`: identical to `seach_with_index`.
|
3294
|
+
|
3295
|
+
- `with_object(<obj>)`: identical to `seach_with_object`.
|
3296
|
+
|
3297
|
+
- `clone`: create a new enumerator on the same elements.
|
3298
|
+
|
3299
|
+
- `+`: concatenation of enumerators.
|
3300
|
+
|
3301
|
+
|
3302
|
+
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:
|
3303
|
+
|
3304
|
+
- `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.
|
3305
|
+
|
3306
|
+
- `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.
|
3307
|
+
|
3308
|
+
- `hchain`: HW implementation of the Ruby `chain`.
|
3309
|
+
|
3310
|
+
- `hmap`: HW implementation of the Ruby `map` method. When used with a block returns a vector signal containing each computation result.
|
3311
|
+
|
3312
|
+
<!-- - `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. -->
|
3313
|
+
|
3314
|
+
- `hcount`: HW implementation of the Ruby `count` method. Returns a signal whose bit width matches the size of the enumerator containing the count result.
|
3315
|
+
|
3316
|
+
<!-- - `hcycle`: HW implementation of the Ruby `cycle` method. -->
|
3317
|
+
|
3318
|
+
- `hfind`: HW implementation of the Ruby `find` method. Returns a signal containing the found element, or 0 if not found.
|
3319
|
+
|
3320
|
+
- `hdrop`: HW implementation of the Ruby `drop` method. Returns a vector signal containing the remaining elements.
|
3321
|
+
|
3322
|
+
<!-- - `hdrop_while`: HW implementation of the Ruby `drop_while` method. Returns a vector signal containing the remaining elements. -->
|
3323
|
+
|
3324
|
+
- `heach_cons`: HW implementation of the Ruby `each_cons` method.
|
3325
|
+
|
3326
|
+
- `heach_slice`: HW implementation of the Ruby `each_slice` method.
|
3327
|
+
|
3328
|
+
- `heach_with_index`: HW implementation of the Ruby `each_with_index` method.
|
3329
|
+
|
3330
|
+
- `heach_with_object`: HW implementation of the Ruby `each_with_object` method.
|
3331
|
+
|
3332
|
+
- `hto_a`: HW implementation of the Ruby `to_a` method. Returns a vector signal containing all the elements of the enumerator.
|
3333
|
+
|
3334
|
+
<!-- - `hselect`: HW implementation of the Ruby `select` method. Returns a vector signal containing the selected elements. -->
|
3335
|
+
|
3336
|
+
- `hfind_index`: HW implementation of the Ruby `find_index` method. Returns the index of the found element or -1 if not.
|
3337
|
+
|
3338
|
+
- `hfirst`: HW implementation of the Ruby `first` method. Returns a vector signal containing the first elements.
|
3339
|
+
|
3340
|
+
- `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.
|
3341
|
+
|
3342
|
+
- `hinject`: HW implementation of the Ruby `inject` method. Return a signal of the type of elements containing the computation result.
|
3343
|
+
|
3344
|
+
- `hmax`: HW implementation of the Ruby `max` method. Return a vector signal containing the found max values.
|
3345
|
+
*Note:* For now only one max value can be returned.
|
3346
|
+
|
3347
|
+
- `hmax_by`: HW implementation of the Ruby `max_by` method. Return a vector signal containing the found max values.
|
3348
|
+
*Note:* For now only one max value can be returned.
|
3349
|
+
|
3350
|
+
- `hmin`: HW implementation of the Ruby `min` method. Return a vector signal containing the found min values.
|
3351
|
+
*Note:* For now only one min value can be returned.
|
3352
|
+
|
3353
|
+
- `hmin_by`: HW implementation of the Ruby `min_by` method. Return a vector signal containing the found min values.
|
3354
|
+
*Note:* For now only one min value can be returned.
|
3355
|
+
|
3356
|
+
- `hminmax`: HW implementation of the Ruby `minmax` method. Returns a 2-element vector signal containing the resulting min and max values.
|
3357
|
+
|
3358
|
+
- `hminmax_by`: HW implementation of the Ruby `minmax_by` method. Returns a 2-element vector signal containing the resulting min and max values.
|
3359
|
+
|
3360
|
+
- `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.
|
3361
|
+
|
3362
|
+
- `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.
|
3363
|
+
|
3364
|
+
<!-- - `hreject`: HW implementation of the Ruby `reject` method. Returns a vector signal containing the remaining elements. -->
|
3365
|
+
|
3366
|
+
- `hreverse_each`: HW implementation of the Ruby `reverse_each` method.
|
3367
|
+
*Note:* This algorithm makes sense inside a `seq` process.
|
3368
|
+
|
3369
|
+
- `hsort`: HW implementation of the Ruby `sort` method. Returns a vector signal containing the sorted elements.
|
3370
|
+
*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).
|
3371
|
+
|
3372
|
+
- `hsort_by`: HW implementation of the Ruby `sort_by` method. Returns a vector signal containing the sorted elements.
|
3373
|
+
*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).
|
3374
|
+
|
3375
|
+
- `hsum`: HW implementation of the Ruby `sum` method. Returns a signal with the type of elements containing the sum result.
|
3376
|
+
|
3377
|
+
- `htake`: HW implementation of the Ruby `take` method. Returns a vector signal containing the taken elements.
|
3378
|
+
|
3379
|
+
<!-- - `htake_while`: HW implementation of the Ruby `take_while` method. Returns a vector signal containing the taken elements. -->
|
3380
|
+
|
3381
|
+
<!-- - `huniq`: HW implementation the Ruby `uniq` method. Returns a vector signal containing the selected elements. -->
|
3382
|
+
|
3383
|
+
|
3255
3384
|
## Sequencer (software-like hardware coding):: `std/sequencer.rb`
|
3256
3385
|
<a name="sequencer"></a>
|
3257
3386
|
|
@@ -3390,9 +3519,9 @@ end
|
|
3390
3519
|
```
|
3391
3520
|
|
3392
3521
|
|
3393
|
-
### HDLRuby enumerators and enumerable objects: `std/sequencer.rb`
|
3522
|
+
### HDLRuby sequential enumerators and enumerable objects: `std/sequencer.rb`
|
3394
3523
|
|
3395
|
-
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.
|
3524
|
+
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.
|
3396
3525
|
|
3397
3526
|
The enumerators can be controlled using the following methods:
|
3398
3527
|
|
@@ -3846,6 +3975,18 @@ File.open("sequencer_in_ruby.rb","w") do |f|
|
|
3846
3975
|
end
|
3847
3976
|
```
|
3848
3977
|
|
3978
|
+
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.
|
3979
|
+
|
3980
|
+
```ruby
|
3981
|
+
File.open("seqiemcer_in_c.c","w" do |f|
|
3982
|
+
f << my_seq.to_c
|
3983
|
+
end
|
3984
|
+
|
3985
|
+
File.open("seqiemcer_in_python.py","w" do |f|
|
3986
|
+
f << my_seq.to_python
|
3987
|
+
end
|
3988
|
+
```
|
3989
|
+
|
3849
3990
|
__Note__: the ruby code for sequencers is compatible with mruby for execution on embedded systems.
|
3850
3991
|
|
3851
3992
|
|
@@ -3986,7 +4127,7 @@ end.()
|
|
3986
4127
|
|
3987
4128
|
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.
|
3988
4129
|
|
3989
|
-
__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
|
4130
|
+
__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:
|
3990
4131
|
|
3991
4132
|
```ruby
|
3992
4133
|
sequencer do
|
@@ -690,13 +690,13 @@ static Value mul_value_defined_bitstring(Value src0, Value src1, Value dst) {
|
|
690
690
|
int sgn1 = (src1->type->flags.sign) && (src1->data_str[width1-1] == '1');
|
691
691
|
// printf("sgn0=%d sgn1=%d\n",(src0->type->flags.sign) && (src0->data_str[width0-1] == '1'),sgn1);
|
692
692
|
Value psrc1;
|
693
|
-
// printf("first
|
693
|
+
// printf("first src1->data_str=%s\n",src1->data_str);fflush(stdout);
|
694
694
|
if (sgn1) {
|
695
695
|
psrc1 = neg_value_bitstring(src1,get_value());
|
696
696
|
} else {
|
697
697
|
psrc1 = src1;
|
698
698
|
}
|
699
|
-
// printf("now
|
699
|
+
// printf("now psrc1->data_str=%s\n",psrc1->data_str);fflush(stdout);
|
700
700
|
/* Perform the multiplying with sucessive shifts and additions. */
|
701
701
|
/* First the result is zero. */
|
702
702
|
const char* str = psrc1->data_str;
|
@@ -778,8 +778,8 @@ static Value mod_value_defined_bitstring(Value src0, Value src1, Value dst) {
|
|
778
778
|
|
779
779
|
|
780
780
|
/** Computes the greater comparision of two defined bitstring values.
|
781
|
-
* @param src0 the first source value of the
|
782
|
-
* @param src1 the second source value of the
|
781
|
+
* @param src0 the first source value of the comparison
|
782
|
+
* @param src1 the second source value of the comparison
|
783
783
|
* @param dst the destination value
|
784
784
|
* @return dst */
|
785
785
|
static Value greater_value_defined_bitstring(Value src0, Value src1, Value dst) {
|
@@ -788,28 +788,13 @@ static Value greater_value_defined_bitstring(Value src0, Value src1, Value dst)
|
|
788
788
|
dst->type = src0->type;
|
789
789
|
dst->numeric = 1;
|
790
790
|
|
791
|
-
// /* Converts the values to integers. */
|
792
|
-
// unsigned long long src0i = value2integer(src0);
|
793
|
-
// unsigned long long src1i = value2integer(src1);
|
794
|
-
// /* Perform the comparison. */
|
795
|
-
// if (src0->type->flags.sign) {
|
796
|
-
// if (src1->type->flags.sign)
|
797
|
-
// dst->data_int = (signed long long)src0i > (signed long long)src1i;
|
798
|
-
// else
|
799
|
-
// dst->data_int = (signed long long)src0i >= 0 ? src0i > src1i : 0;
|
800
|
-
// } else {
|
801
|
-
// if (src1->type->flags.sign)
|
802
|
-
// dst->data_int = (signed long long)src1i >= 0 ? src0i > src1i : 1;
|
803
|
-
// else
|
804
|
-
// dst->data_int = src0i > src1i;
|
805
|
-
// }
|
806
791
|
char* src0_data = src0->data_str;
|
807
792
|
char* src1_data = src1->data_str;
|
808
793
|
long long width0 = type_width(src0->type);
|
809
794
|
long long width1 = type_width(src1->type);
|
810
795
|
long long width = width0>width1 ? width0 : width1;
|
811
|
-
if (src0->type->flags.sign && src0_data[width0-1] == '1') {
|
812
|
-
if(src1->type->flags.sign && src1_data[width1-1] == '1') {
|
796
|
+
if (src0->type->flags.sign && (src0_data[width0-1] == '1')) {
|
797
|
+
if(src1->type->flags.sign && (src1_data[width1-1] == '1')) {
|
813
798
|
/* Negative-negative comparison. */
|
814
799
|
for(long long i=width-1; i >= 0; --i) {
|
815
800
|
char d0 = i >= width0 ? '1' : src0_data[i];
|
@@ -828,7 +813,7 @@ static Value greater_value_defined_bitstring(Value src0, Value src1, Value dst)
|
|
828
813
|
return dst;
|
829
814
|
}
|
830
815
|
} else {
|
831
|
-
if(src1->type->flags.sign && src1_data[width1-1] == '1') {
|
816
|
+
if(src1->type->flags.sign && (src1_data[width1-1] == '1')) {
|
832
817
|
/* Positive-negative comparison, src0 is greater. */
|
833
818
|
dst->data_int = 1;
|
834
819
|
return dst;
|
@@ -852,9 +837,72 @@ static Value greater_value_defined_bitstring(Value src0, Value src1, Value dst)
|
|
852
837
|
return dst;
|
853
838
|
}
|
854
839
|
|
840
|
+
/** Computes the greater comparision of a numeric value and a
|
841
|
+
* defined bitstring values.
|
842
|
+
* @param src0 the first source value of the comparison
|
843
|
+
* @param src1 the second source value of the comparison
|
844
|
+
* @param dst the destination value
|
845
|
+
* @return dst */
|
846
|
+
static Value greater_value_numeric_defined_bitstring(Value src0, Value src1, Value dst) {
|
847
|
+
// printf("greater_value_numeric_defined_bitstring.\n");
|
848
|
+
/* Sets state of the destination using the first source. */
|
849
|
+
dst->type = src0->type;
|
850
|
+
dst->numeric = 1;
|
851
|
+
|
852
|
+
unsigned long long src0_int = src0->data_int;
|
853
|
+
char* src1_data = src1->data_str;
|
854
|
+
long long width0 = type_width(src0->type);
|
855
|
+
long long width1 = type_width(src1->type);
|
856
|
+
long long width = width0>width1 ? width0 : width1;
|
857
|
+
if (src0->type->flags.sign && (src0_int & (1 << (width0-1)))) {
|
858
|
+
if(src1->type->flags.sign && (src1_data[width1-1] == '1')) {
|
859
|
+
/* Negative-negative comparison. */
|
860
|
+
for(long long i=width-1; i >= 0; --i) {
|
861
|
+
char d0 = i >= width0 ? '1' :
|
862
|
+
((src0_int & (1 << i)) ? '1' : '0');
|
863
|
+
char d1 = i >= width1 ? '1' : src1_data[i];
|
864
|
+
if (d0 < d1) {
|
865
|
+
dst->data_int = 0;
|
866
|
+
return dst;
|
867
|
+
} else if (d0 > d1) {
|
868
|
+
dst->data_int = 1;
|
869
|
+
return dst;
|
870
|
+
}
|
871
|
+
}
|
872
|
+
} else {
|
873
|
+
/* Negative positive comparison, src0 is smaller. */
|
874
|
+
dst->data_int = 0;
|
875
|
+
return dst;
|
876
|
+
}
|
877
|
+
} else {
|
878
|
+
if(src1->type->flags.sign && (src1_data[width1-1] == '1')) {
|
879
|
+
/* Positive-negative comparison, src0 is greater. */
|
880
|
+
dst->data_int = 1;
|
881
|
+
return dst;
|
882
|
+
} else {
|
883
|
+
/* Positive-positive comparison. */
|
884
|
+
for(long long i=width-1; i >= 0; --i) {
|
885
|
+
char d0 = i >= width0 ? '0' :
|
886
|
+
((src0_int & (1 << i)) ? '1' : '0');
|
887
|
+
char d1 = i >= width1 ? '0' : src1_data[i];
|
888
|
+
if (d0 < d1) {
|
889
|
+
dst->data_int = 0;
|
890
|
+
return dst;
|
891
|
+
} else if (d0 > d1) {
|
892
|
+
dst->data_int = 1;
|
893
|
+
return dst;
|
894
|
+
}
|
895
|
+
}
|
896
|
+
}
|
897
|
+
}
|
898
|
+
/* Equality. */
|
899
|
+
dst->data_int = 0;
|
900
|
+
return dst;
|
901
|
+
}
|
902
|
+
|
855
903
|
/** Computes the lesser comparision of two defined bitstring values.
|
856
|
-
* @param src0 the first source value of the
|
857
|
-
* @param src1 the second source value of the
|
904
|
+
* @param src0 the first source value of the comparison
|
905
|
+
* @param src1 the second source value of the comparison
|
858
906
|
* @param dst the destination value
|
859
907
|
* @return dst */
|
860
908
|
static Value lesser_value_defined_bitstring(Value src0, Value src1, Value dst) {
|
@@ -863,21 +911,6 @@ static Value lesser_value_defined_bitstring(Value src0, Value src1, Value dst) {
|
|
863
911
|
dst->type = src0->type;
|
864
912
|
dst->numeric = 1;
|
865
913
|
|
866
|
-
// /* Converts the values to integers. */
|
867
|
-
// unsigned long long src0i = value2integer(src0);
|
868
|
-
// unsigned long long src1i = value2integer(src1);
|
869
|
-
// /* Perform the comparison. */
|
870
|
-
// if (src0->type->flags.sign) {
|
871
|
-
// if (src1->type->flags.sign)
|
872
|
-
// dst->data_int = (signed long long)src0i < (signed long long)src1i;
|
873
|
-
// else
|
874
|
-
// dst->data_int = (signed long long)src0i >= 0 ? src0i < src1i : 1;
|
875
|
-
// } else {
|
876
|
-
// if (src1->type->flags.sign)
|
877
|
-
// dst->data_int = (signed long long)src1i >= 0 ? src0i < src1i : 0;
|
878
|
-
// else
|
879
|
-
// dst->data_int = src0i < src1i;
|
880
|
-
// }
|
881
914
|
char* src0_data = src0->data_str;
|
882
915
|
char* src1_data = src1->data_str;
|
883
916
|
long long width0 = type_width(src0->type);
|
@@ -927,32 +960,80 @@ static Value lesser_value_defined_bitstring(Value src0, Value src1, Value dst) {
|
|
927
960
|
return dst;
|
928
961
|
}
|
929
962
|
|
963
|
+
/** Computes the lesser comparision of one numeric value and one
|
964
|
+
* defined bitstring values.
|
965
|
+
* @param src0 the first source value of the comparison
|
966
|
+
* @param src1 the second source value of the comparison
|
967
|
+
* @param dst the destination value
|
968
|
+
* @return dst */
|
969
|
+
static Value lesser_value_numeric_defined_bitstring(Value src0, Value src1, Value dst) {
|
970
|
+
// printf("lesser_value_numeric_defined_bitstring.\n");
|
971
|
+
/* Sets state of the destination using the first source. */
|
972
|
+
dst->type = src0->type;
|
973
|
+
dst->numeric = 1;
|
974
|
+
|
975
|
+
unsigned long long src0_int = src0->data_int;
|
976
|
+
char* src1_data = src1->data_str;
|
977
|
+
long long width0 = type_width(src0->type);
|
978
|
+
long long width1 = type_width(src1->type);
|
979
|
+
long long width = width0>width1 ? width0 : width1;
|
980
|
+
if (src0->type->flags.sign && (src0_int & (1 << (width0-1)))) {
|
981
|
+
if(src1->type->flags.sign && src1_data[width1-1] == '1') {
|
982
|
+
/* Negative-negative comparison. */
|
983
|
+
for(long long i=width-1; i >= 0; --i) {
|
984
|
+
char d0 = i >= width0 ? '1' :
|
985
|
+
((src0_int & (1 << i)) ? '1' : '0');
|
986
|
+
char d1 = i >= width1 ? '1' : src1_data[i];
|
987
|
+
if (d0 < d1) {
|
988
|
+
dst->data_int = 1;
|
989
|
+
return dst;
|
990
|
+
} else if (d0 > d1) {
|
991
|
+
dst->data_int = 0;
|
992
|
+
return dst;
|
993
|
+
}
|
994
|
+
}
|
995
|
+
} else {
|
996
|
+
/* Negative positive comparison, src0 is smaller. */
|
997
|
+
dst->data_int = 1;
|
998
|
+
return dst;
|
999
|
+
}
|
1000
|
+
} else {
|
1001
|
+
if(src1->type->flags.sign && src1_data[width1-1] == '1') {
|
1002
|
+
/* Positive-negative comparison, src0 is greater. */
|
1003
|
+
dst->data_int = 0;
|
1004
|
+
return dst;
|
1005
|
+
} else {
|
1006
|
+
/* Positive-positive comparison. */
|
1007
|
+
for(long long i=width-1; i >= 0; --i) {
|
1008
|
+
char d0 = i >= width0 ? '0' :
|
1009
|
+
((src0_int & (1 << i)) ? '1' : '0');
|
1010
|
+
char d1 = i >= width1 ? '0' : src1_data[i];
|
1011
|
+
if (d0 < d1) {
|
1012
|
+
dst->data_int = 1;
|
1013
|
+
return dst;
|
1014
|
+
} else if (d0 > d1) {
|
1015
|
+
dst->data_int = 0;
|
1016
|
+
return dst;
|
1017
|
+
}
|
1018
|
+
}
|
1019
|
+
}
|
1020
|
+
}
|
1021
|
+
/* Equality. */
|
1022
|
+
dst->data_int = 0;
|
1023
|
+
return dst;
|
1024
|
+
}
|
1025
|
+
|
930
1026
|
/** Computes the greater or equal comparision of two defined bitstring values.
|
931
|
-
* @param src0 the first source value of the
|
932
|
-
* @param src1 the second source value of the
|
1027
|
+
* @param src0 the first source value of the comparison
|
1028
|
+
* @param src1 the second source value of the comparison
|
933
1029
|
* @param dst the destination value
|
934
1030
|
* @return dst */
|
935
1031
|
static Value greater_equal_value_defined_bitstring(Value src0, Value src1, Value dst) {
|
1032
|
+
// printf("greater_equal_value_defined_bitstring.\n");
|
936
1033
|
/* Sets state of the destination using the first source. */
|
937
1034
|
dst->type = src0->type;
|
938
1035
|
dst->numeric = 1;
|
939
1036
|
|
940
|
-
// /* Converts the values to integers. */
|
941
|
-
// unsigned long long src0i = value2integer(src0);
|
942
|
-
// unsigned long long src1i = value2integer(src1);
|
943
|
-
// // printf("src0i=%lld src1i=%lld, src0i.sign=%d src0i.width=%d, src1i.sign=%d src1i.width=%d\n",src0i,src1i,src0->type->flags.sign,type_width(src0->type),src1->type->flags.sign,type_width(src1->type));
|
944
|
-
// /* Perform the comparison. */
|
945
|
-
// if (src0->type->flags.sign) {
|
946
|
-
// if (src1->type->flags.sign)
|
947
|
-
// dst->data_int = (signed long long)src0i >= (signed long long)src1i;
|
948
|
-
// else
|
949
|
-
// dst->data_int = (signed long long)src0i >= 0 ? src0i >= src1i : 0;
|
950
|
-
// } else {
|
951
|
-
// if (src1->type->flags.sign)
|
952
|
-
// dst->data_int = (signed long long)src1i >= 0 ? src0i >= src1i : 1;
|
953
|
-
// else
|
954
|
-
// dst->data_int = src0i >= src1i;
|
955
|
-
// }
|
956
1037
|
char* src0_data = src0->data_str;
|
957
1038
|
char* src1_data = src1->data_str;
|
958
1039
|
long long width0 = type_width(src0->type);
|
@@ -1002,31 +1083,80 @@ static Value greater_equal_value_defined_bitstring(Value src0, Value src1, Value
|
|
1002
1083
|
return dst;
|
1003
1084
|
}
|
1004
1085
|
|
1086
|
+
/** Computes the greater or equal comparision of numeric and one
|
1087
|
+
* defined bitstring values.
|
1088
|
+
* @param src0 the first source value of the comparison
|
1089
|
+
* @param src1 the second source value of the comparison
|
1090
|
+
* @param dst the destination value
|
1091
|
+
* @return dst */
|
1092
|
+
static Value greater_equal_value_numeric_defined_bitstring(Value src0, Value src1, Value dst) {
|
1093
|
+
// printf("greater_equal_value_numeric_defined_bitstring.\n");
|
1094
|
+
/* Sets state of the destination using the first source. */
|
1095
|
+
dst->type = src0->type;
|
1096
|
+
dst->numeric = 1;
|
1097
|
+
|
1098
|
+
unsigned long long src0_int = src0->data_int;
|
1099
|
+
char* src1_data = src1->data_str;
|
1100
|
+
long long width0 = type_width(src0->type);
|
1101
|
+
long long width1 = type_width(src1->type);
|
1102
|
+
long long width = width0>width1 ? width0 : width1;
|
1103
|
+
if (src0->type->flags.sign && (src0_int & (1 <<(width0-1)))) {
|
1104
|
+
if(src1->type->flags.sign && src1_data[width1-1] == '1') {
|
1105
|
+
/* Negative-negative comparison. */
|
1106
|
+
for(long long i=width-1; i >= 0; --i) {
|
1107
|
+
char d0 = i >= width0 ? '1' :
|
1108
|
+
((src0_int & (1 << i)) ? '1' : '0');
|
1109
|
+
char d1 = i >= width1 ? '1' : src1_data[i];
|
1110
|
+
if (d0 < d1) {
|
1111
|
+
dst->data_int = 0;
|
1112
|
+
return dst;
|
1113
|
+
} else if (d0 > d1) {
|
1114
|
+
dst->data_int = 1;
|
1115
|
+
return dst;
|
1116
|
+
}
|
1117
|
+
}
|
1118
|
+
} else {
|
1119
|
+
/* Negative positive comparison, src0 is smaller. */
|
1120
|
+
dst->data_int = 0;
|
1121
|
+
return dst;
|
1122
|
+
}
|
1123
|
+
} else {
|
1124
|
+
if(src1->type->flags.sign && src1_data[width1-1] == '1') {
|
1125
|
+
/* Positive-negative comparison, src0 is greater. */
|
1126
|
+
dst->data_int = 1;
|
1127
|
+
return dst;
|
1128
|
+
} else {
|
1129
|
+
/* Positive-positive comparison. */
|
1130
|
+
for(long long i=width-1; i >= 0; --i) {
|
1131
|
+
char d0 = i >= width0 ? '0' :
|
1132
|
+
((src0_int & (1 << i)) ? '1' : '0');
|
1133
|
+
char d1 = i >= width1 ? '0' : src1_data[i];
|
1134
|
+
if (d0 < d1) {
|
1135
|
+
dst->data_int = 0;
|
1136
|
+
return dst;
|
1137
|
+
} else if (d0 > d1) {
|
1138
|
+
dst->data_int = 1;
|
1139
|
+
return dst;
|
1140
|
+
}
|
1141
|
+
}
|
1142
|
+
}
|
1143
|
+
}
|
1144
|
+
/* Equality. */
|
1145
|
+
dst->data_int = 1;
|
1146
|
+
return dst;
|
1147
|
+
}
|
1148
|
+
|
1005
1149
|
/** Computes the lesser or equal comparision of two defined bitstring values.
|
1006
1150
|
* @param src0 the first source value of the addition
|
1007
1151
|
* @param src1 the second source value of the addition
|
1008
1152
|
* @param dst the destination value
|
1009
1153
|
* @return dst */
|
1010
1154
|
static Value lesser_equal_value_defined_bitstring(Value src0, Value src1, Value dst) {
|
1155
|
+
// printf("lesser_equal_value_defined_bitstring.\n");
|
1011
1156
|
/* Sets state of the destination using the first source. */
|
1012
1157
|
dst->type = src0->type;
|
1013
1158
|
dst->numeric = 1;
|
1014
1159
|
|
1015
|
-
// /* Converts the values to integers. */
|
1016
|
-
// unsigned long long src0i = value2integer(src0);
|
1017
|
-
// unsigned long long src1i = value2integer(src1);
|
1018
|
-
// /* Perform the comparison. */
|
1019
|
-
// if (src0->type->flags.sign) {
|
1020
|
-
// if (src1->type->flags.sign)
|
1021
|
-
// dst->data_int = (signed long long)src0i <= (signed long long)src1i;
|
1022
|
-
// else
|
1023
|
-
// dst->data_int = (signed long long)src0i >= 0 ? src0i <= src1i : 1;
|
1024
|
-
// } else {
|
1025
|
-
// if (src1->type->flags.sign)
|
1026
|
-
// dst->data_int = (signed long long)src1i >= 0 ? src0i <= src1i : 0;
|
1027
|
-
// else
|
1028
|
-
// dst->data_int = src0i <= src1i;
|
1029
|
-
// }
|
1030
1160
|
char* src0_data = src0->data_str;
|
1031
1161
|
char* src1_data = src1->data_str;
|
1032
1162
|
long long width0 = type_width(src0->type);
|
@@ -1076,6 +1206,70 @@ static Value lesser_equal_value_defined_bitstring(Value src0, Value src1, Value
|
|
1076
1206
|
return dst;
|
1077
1207
|
}
|
1078
1208
|
|
1209
|
+
/** Computes the lesser or equal comparision of on numeric value and one
|
1210
|
+
* defined bitstring values.
|
1211
|
+
* @param src0 the first source value of the addition
|
1212
|
+
* @param src1 the second source value of the addition
|
1213
|
+
* @param dst the destination value
|
1214
|
+
* @return dst */
|
1215
|
+
static Value lesser_equal_value_numeric_defined_bitstring(Value src0, Value src1, Value dst) {
|
1216
|
+
// printf("lesser_equal_value_numeric_defined_bitstring.\n");
|
1217
|
+
/* Sets state of the destination using the first source. */
|
1218
|
+
dst->type = src0->type;
|
1219
|
+
dst->numeric = 1;
|
1220
|
+
|
1221
|
+
unsigned long long src0_int = src0->data_int;
|
1222
|
+
char* src1_data = src1->data_str;
|
1223
|
+
long long width0 = type_width(src0->type);
|
1224
|
+
long long width1 = type_width(src1->type);
|
1225
|
+
long long width = width0>width1 ? width0 : width1;
|
1226
|
+
if (src0->type->flags.sign && (src0_int & (1 << (width0-1)))) {
|
1227
|
+
if(src1->type->flags.sign && src1_data[width1-1] == '1') {
|
1228
|
+
/* Negative-negative comparison. */
|
1229
|
+
for(long long i=width-1; i >= 0; --i) {
|
1230
|
+
char d0 = i >= width0 ? '1' :
|
1231
|
+
((src0_int & (1 << i)) ? '1' : '0');
|
1232
|
+
char d1 = i >= width1 ? '1' : src1_data[i];
|
1233
|
+
if (d0 < d1) {
|
1234
|
+
dst->data_int = 1;
|
1235
|
+
return dst;
|
1236
|
+
} else if (d0 > d1) {
|
1237
|
+
dst->data_int = 0;
|
1238
|
+
return dst;
|
1239
|
+
}
|
1240
|
+
}
|
1241
|
+
} else {
|
1242
|
+
/* Negative positive comparison, src0 is smaller. */
|
1243
|
+
dst->data_int = 1;
|
1244
|
+
return dst;
|
1245
|
+
}
|
1246
|
+
} else {
|
1247
|
+
if(src1->type->flags.sign && src1_data[width1-1] == '1') {
|
1248
|
+
/* Positive-negative comparison, src0 is greater. */
|
1249
|
+
dst->data_int = 0;
|
1250
|
+
return dst;
|
1251
|
+
} else {
|
1252
|
+
/* Positive-positive comparison. */
|
1253
|
+
for(long long i=width-1; i >= 0; --i) {
|
1254
|
+
char d0 = i >= width0 ? '0' :
|
1255
|
+
((src0_int & (1 << i)) ? '1' : '0');
|
1256
|
+
char d1 = i >= width1 ? '0' : src1_data[i];
|
1257
|
+
// printf("d0=%c d1=%c\n",d0,d1);
|
1258
|
+
if (d0 < d1) {
|
1259
|
+
dst->data_int = 1;
|
1260
|
+
return dst;
|
1261
|
+
} else if (d0 > d1) {
|
1262
|
+
dst->data_int = 0;
|
1263
|
+
return dst;
|
1264
|
+
}
|
1265
|
+
}
|
1266
|
+
}
|
1267
|
+
}
|
1268
|
+
/* Equality. */
|
1269
|
+
dst->data_int = 1;
|
1270
|
+
return dst;
|
1271
|
+
}
|
1272
|
+
|
1079
1273
|
|
1080
1274
|
/** Computes the NOT of a bitstring value.
|
1081
1275
|
* @param src the source value of the not
|
@@ -3111,6 +3305,10 @@ Value greater_value(Value src0, Value src1, Value dst) {
|
|
3111
3305
|
/* Both sources are numeric. */
|
3112
3306
|
return greater_value_numeric(src0,src1,dst);
|
3113
3307
|
} else if (is_defined_value(src0) && is_defined_value(src1)) {
|
3308
|
+
if (src0->numeric)
|
3309
|
+
return greater_value_numeric_defined_bitstring(src0,src1,dst);
|
3310
|
+
if (src1->numeric)
|
3311
|
+
return lesser_equal_value_numeric_defined_bitstring(src1,src0,dst);
|
3114
3312
|
/* Both sources can be converted to numeric values. */
|
3115
3313
|
return greater_value_defined_bitstring(src0,src1,dst);
|
3116
3314
|
} else {
|
@@ -3139,6 +3337,10 @@ Value lesser_value(Value src0, Value src1, Value dst) {
|
|
3139
3337
|
return lesser_value_numeric(src0,src1,dst);
|
3140
3338
|
} else if (is_defined_value(src0) && is_defined_value(src1)) {
|
3141
3339
|
/* Both sources can be converted to numeric values. */
|
3340
|
+
if (src0->numeric)
|
3341
|
+
return lesser_value_numeric_defined_bitstring(src0,src1,dst);
|
3342
|
+
if (src1->numeric)
|
3343
|
+
return greater_equal_value_numeric_defined_bitstring(src1,src0,dst);
|
3142
3344
|
return lesser_value_defined_bitstring(src0,src1,dst);
|
3143
3345
|
} else {
|
3144
3346
|
/* Cannot compute (for now), simply undefines the destination. */
|
@@ -3166,6 +3368,10 @@ Value greater_equal_value(Value src0, Value src1, Value dst) {
|
|
3166
3368
|
return greater_equal_value_numeric(src0,src1,dst);
|
3167
3369
|
} else if (is_defined_value(src0) && is_defined_value(src1)) {
|
3168
3370
|
/* Both sources can be converted to numeric values. */
|
3371
|
+
if (src0->numeric)
|
3372
|
+
return greater_equal_value_numeric_defined_bitstring(src0,src1,dst);
|
3373
|
+
if (src1->numeric)
|
3374
|
+
return lesser_value_numeric_defined_bitstring(src1,src0,dst);
|
3169
3375
|
return greater_equal_value_defined_bitstring(src0,src1,dst);
|
3170
3376
|
} else {
|
3171
3377
|
/* Cannot compute (for now), simply undefines the destination. */
|
@@ -3192,6 +3398,10 @@ Value lesser_equal_value(Value src0, Value src1, Value dst) {
|
|
3192
3398
|
return lesser_equal_value_numeric(src0,src1,dst);
|
3193
3399
|
} else if (is_defined_value(src0) && is_defined_value(src1)) {
|
3194
3400
|
/* Both sources can be converted to numeric values. */
|
3401
|
+
if (src0->numeric)
|
3402
|
+
return lesser_equal_value_numeric_defined_bitstring(src0,src1,dst);
|
3403
|
+
if (src1->numeric)
|
3404
|
+
return greater_value_numeric_defined_bitstring(src1,src0,dst);
|
3195
3405
|
return lesser_equal_value_defined_bitstring(src0,src1,dst);
|
3196
3406
|
} else {
|
3197
3407
|
/* Cannot compute (for now), simply undefines the destination. */
|