HDLRuby 3.9.5 → 3.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2158fa1453147b4f00983a8e182f592a7878a3314fdabb351e79da00c99eb875
4
- data.tar.gz: db538f8d85886189c4d309acf9ed6e5e9239e0bbe7a7b380c22a768d20eca52f
3
+ metadata.gz: d8c62653a5b0c4fa2e8a42e0c1198d3a0e714be890e4caf80058532150117b51
4
+ data.tar.gz: 6ec87f18f390bebb88d19bffce01a6ab7420d9f82777685d4ec330d0b5f2be34
5
5
  SHA512:
6
- metadata.gz: 210bf9b4b29db252d1c7364d70aea07473381e8eb5500cf936edae1f01cd67d37cff69e5cff9391b65b6265b3e8261f87ec8335b75cae577379fe70304f0ef78
7
- data.tar.gz: 7c4e9e1ff74dcba76224505182b506363f772795a45e1608918d4b60648faed104b3776fdb459964e9900633448bbdb59af6c8259e309d9da329f6834c250f8b
6
+ metadata.gz: 4f88b4dea7c80c6fda808d63c718f64af2a1e2e8d6371b68ef50757347dc4d5b3232741151494e74f76251a451e03ed498fb2bb1ff85281f524a23ebf4494000
7
+ data.tar.gz: 49bb526022624a3654097d032ba6314b0725e7a6cbc9d4d82b71996058ba392196152c74e71d64c05a7ab5381866b95a9a357af21de3c447a3505526b6a95e4c
data/README.md CHANGED
@@ -71,6 +71,24 @@ hdrcc --get-tuto
71
71
 
72
72
  __What's New__
73
73
 
74
+ For HDLRuby version 3.9.6/3.9.7:
75
+
76
+ * Added the bit-level decoder and the expression decoder.
77
+
78
+ * Added `auto_connect` for letting HDLRuby looking for the signals to connect to the instances.
79
+
80
+ * Now, `hbreak` allows end of process if present in the top hif.
81
+
82
+ * Added bit extension in literals.
83
+
84
+ * Added the expression hif.
85
+
86
+ * Added the unary logic operators for bit reduction.
87
+
88
+ * Removed 'nxor' and added 'eq' instead.
89
+
90
+ * Various bug fixes.
91
+
74
92
  For HDLRuby version 3.9.3/3.9.4/3.9.5:
75
93
 
76
94
  * Improved the graphical representation of the RTL code in SVG format for faster generation and better rendering. The tool is still experimental though.
@@ -473,9 +491,9 @@ Conditional statements, common in RTL languages, are also supported in HDLRuby.
473
491
 
474
492
  These include:
475
493
 
476
- * `hif` / `helsif` / `helse` for `if`-like conditionals
494
+ * `hif` / `helsif` / `helse` for `if`-like conditionals statements and expression.
477
495
 
478
- * `hcase` / `hwhen` / `helse` for `case`-like conditionals
496
+ * `hcase` / `hcasez` / `hwhen` / `helse` for `case`-like conditionals
479
497
 
480
498
  * `mux`, an expression-level construct for multiplexers, which supports multiple inputs, unlike the ?: ternary operator in Verilog, which only handles two
481
499
 
@@ -501,6 +519,29 @@ The conditional logic above can also be written more compactly using the `mux` e
501
519
  [cout,z] <= x.as(bit[8..0]) + mux(addbsub, y, ~y + 1)
502
520
  ```
503
521
 
522
+ Or alternatively, the expression `hif` can be used too:
523
+
524
+ ```ruby
525
+ [cout,z} <= x.as(bit[8..0] + hif(addbsub,~y + 1, y)
526
+ ```
527
+
528
+ __Note__
529
+
530
+ * The `mux` expression orders its choices by selection value, whereas the `hif` expression puts the true case first, as expected for an if condition.
531
+
532
+ * The `hif` expressions can be cascades using the dot `.` operator.
533
+ For example the following code can be rewritten by a simple statement as given in the next code:
534
+
535
+ ```ruby
536
+ hif(x<a) { z <= 1 }
537
+ helsif(x<b) { z <= 2 }
538
+ helsif(x<c) { z <= 3 }
539
+ helse { z <= 0 }
540
+ ```
541
+
542
+ ```ruby
543
+ z <= hif(x<a,1).(x<b,2).(x<c,3,0)
544
+ ```
504
545
 
505
546
  ---
506
547
 
@@ -532,6 +573,43 @@ In this example:
532
573
 
533
574
  It is also possible to connect only a subset of the ports at instantiation time, and to reconnect or override ports later in the code.
534
575
 
576
+ Also, it is possible to let HDLRuby look for the signals to connect using `auto_connect` as shown in the following example:
577
+
578
+ ```ruby
579
+ system :adder do
580
+ [8].input :x, :y
581
+ [8].output :z
582
+
583
+ z <= x + y
584
+ end
585
+
586
+ system :using_adder do
587
+
588
+ [8].inner :x, :y, :z
589
+
590
+ adder(:my_adder).auto_connect
591
+ end
592
+ ```
593
+
594
+ In the example above, HDLRuby will connect automatically the signals `x`, `y`, and `z` from `using_adder` to the adder `my_adder`.
595
+
596
+ Alternatively, you can ask for auto connecting specific ports by giving the port name only. For example, the above auto connection can be described as follows for signal `x`, while connection of `y` and `z` are not automatic:
597
+
598
+ ```ruby
599
+ system :using_adder do
600
+
601
+ [8].inner :x, :y0, :z0
602
+
603
+ adder(:my_adder).(x:, y: y0, z: z0)
604
+ end
605
+ ```
606
+
607
+ __Notes__:
608
+
609
+ * Auto connection only works if the names of the signals match exactly those of the instance.
610
+
611
+ * Auto connection will ignore the signals whose connection is not found.
612
+
535
613
  ---
536
614
 
537
615
  To simulate a circuit, you must write a test bench using `timed` constructs, which describe how signals evolve over time.
@@ -1793,7 +1871,7 @@ The behavior of an assignment statement depends on the execution mode of the enc
1793
1871
 
1794
1872
  ### Control Statements
1795
1873
 
1796
- There are two types of control statements in HDLRuby: the hardware if (`hif`) and the hardware case (`hcase`).
1874
+ There are two types of control statements in HDLRuby: the hardware if (`hif`) the hardware case (`hcase`), and the hardware case with wildcards (`hcasez`).
1797
1875
 
1798
1876
  #### hif
1799
1877
 
@@ -1820,6 +1898,30 @@ end
1820
1898
  ...
1821
1899
  ```
1822
1900
 
1901
+ #### hcasez
1902
+
1903
+ The `hcasez` construct consists of an expression and a list of value-block pairs. A block is executed when its corresponding value matches the value of the `hcasez` expression. If the value contains wildcard digits represented by a `z` they match any corresponding digit. It is declared as follows:
1904
+
1905
+ ```ruby
1906
+ hcasez <expression>
1907
+ hwhen <value 0> do
1908
+ <block contents 0>
1909
+ end
1910
+ hwhen <value 1> do
1911
+ <block contents 1>
1912
+ end
1913
+ ...
1914
+ ```
1915
+
1916
+ As an example of wildcard, the following statement will be executed if val is equal to 5 or 7:
1917
+
1918
+ ```ruby
1919
+ hcasez val
1920
+ hwhen _b01z1 do
1921
+ <block contents 0>
1922
+ end
1923
+ ```
1924
+
1823
1925
  #### helse
1824
1926
 
1825
1927
  You can add a block that is executed when the condition of an `hif` is not met, or when no case in an hcase matches, using the `helse` keyword:
@@ -1977,7 +2079,7 @@ They include [immediate values](#immediate-values), [reference to signals](#refe
1977
2079
 
1978
2080
  ### Immediate values
1979
2081
 
1980
- mmediate values in HDLRuby can represent vectors of type `bit`, `unsigned`, or `signed`, as well as `integer` or `float` numbers. They are prefixed with an underscore (`_`) and include a header indicating the vector type and the numeric base, followed by the actual number.
2082
+ Immediate values in HDLRuby can represent vectors of type `bit`, `unsigned`, or `signed`, as well as `integer` or `float` numbers. They are prefixed with an underscore (`_`) and include a header indicating the vector type and the numeric base, followed by the actual number.
1981
2083
 
1982
2084
  By default, the bit width is inferred from the length of the numeral, but it can also be explicitly specified in the header. Underscores (`_`) can be inserted anywhere within the number to improve readability—they are ignored by the parser.
1983
2085
 
@@ -2006,6 +2108,7 @@ All the following immediate values represent the value `100`, using different ba
2006
2108
  ```ruby
2007
2109
  _bb01100100
2008
2110
  _b8b110_0100
2111
+ _8b1100100
2009
2112
  _u8d100
2010
2113
  _s8d100
2011
2114
  _uh64
@@ -2021,6 +2124,10 @@ _o144
2021
2124
 
2022
2125
  __Notes__:
2023
2126
 
2127
+ * If the bit width given in the header is smaller than the bit width inferred from the numeral, the upper bits will be truncated. For example, the value of `_2b101` is truncated to `_b01`, i.e., one.
2128
+
2129
+ * If the bit width given in the header is larger than the bit width inferred from the numeral, the numeral is extended by duplicating the most significant bit. For example, the value of `_4b1` is extended to `_b1111`, the value of `_8h1` is extended to `_b00000001` and the value of `_5ox` is extended to `_bxxxxx`.
2130
+
2024
2131
  * The form `_01100100` was previously treated as equivalent to `_b01100100`, but due to compatibility issues with recent versions of Ruby, it is now deprecated.
2025
2132
 
2026
2133
  * You may also use Ruby-style immediate values. Their bit width will be automatically adjusted to match the data type of the expression in which they are used. Note, however, that this adjustment may change the value. For example, in the following code, sig is assigned the value `4` (not `100`):
@@ -2113,8 +2220,13 @@ __Logic and Shift Operators:__
2113
2220
  | :--- | :--- |
2114
2221
  | `&` | Bitwise/logical AND |
2115
2222
  | `|` | Bitwise/logical OR |
2223
+ | `^` | Bitwise/logical XOR |
2116
2224
  | `~` | Bitwise/logical NOT |
2225
+ | `.&` | Bitwise/logical AND reduction (postfix) |
2226
+ | `.|` | Bitwise/logical OR reduction (postfix) |
2227
+ | `.^` | Bitwise/logical XOR reduction (postfix) |
2117
2228
  | `mux` | Multiplex |
2229
+ | `hif` | Expression if |
2118
2230
  | `<<`/`ls` | Left shift |
2119
2231
  | `>>`/`rs` | Right shift |
2120
2232
  | `lr` | Left rotate |
@@ -2150,7 +2262,7 @@ __Notes__:
2150
2262
 
2151
2263
  * Ruby does not allow overriding of the `&&`, `||`, or `?:` (ternary) operators, so they are not available in HDLRuby.
2152
2264
 
2153
- - Instead of the `?:` operator, HDLRuby provides the more general mux (multiplexer) operator.
2265
+ - Instead of the `?:` operator, HDLRuby provides the more general mux (multiplexer) operator or expression hif operator.
2154
2266
 
2155
2267
  - HDLRuby does not provide replacements for `&&` and `||`; see the [Logic and Shift Operators](#logic-and-shift-operators) section for an explanation.
2156
2268
 
@@ -2189,7 +2301,11 @@ In HDLRuby, all logic operators are bitwise. To perform Boolean logic operations
2189
2301
 
2190
2302
  * Unary: `~`
2191
2303
 
2192
- These behave the same way as their Ruby counterparts.
2304
+ * Unary Postfix: `.&`, `.|`, `.^`
2305
+
2306
+ The binary and unary operators behave the same way as their Ruby counterparts.
2307
+
2308
+ The unary postfix operators are specific to HDLRuby and perform the reduction of the bits of an expression using the indicated boolean operations. For example `_b101.|` results to `1` since `1 or 0 or 1=1`.
2193
2309
 
2194
2310
  __Note__: There are no Boolean (`&&`, `||`) operators in HDLRuby for two reasons:
2195
2311
 
@@ -3735,9 +3851,11 @@ The second construct is the `before` statement that activates a block until a gi
3735
3851
 
3736
3852
  ## Decoder
3737
3853
 
3738
- The decoder library provides a new set of control statements for easily describing instruction decoders.
3854
+ The decoder library provides a new set of control statements for easily describing decoders circuits. There are three types of decoder descriptions: the procedural decoders, the bit-level decoders, and the expression decoders. They are detailed in the next sections.
3739
3855
 
3740
- A decoder can be declared anywhere within a module definition using the `decoder` keyword, as shown below:
3856
+ ### Procedural Decoder
3857
+
3858
+ A procedural decoder can be declared anywhere within a module definition using the `decoder` keyword, as shown below:
3741
3859
 
3742
3860
  ```ruby
3743
3861
  decoder(<signal>) <block>
@@ -3778,6 +3896,38 @@ end
3778
3896
 
3779
3897
  Note that field bits do not need to be contiguous. For example, field `z` in the second entry spans non-adjacent bits.
3780
3898
 
3899
+ ### Bit-level Decoder
3900
+
3901
+ The bit-level decoder sets or resets individually a set of bit depending on the values of expressions. It takes as primary argument the list of expressions that are to be decoded, and then a cascade of arguments through the successive use of the `.()` operator as follows:
3902
+
3903
+ ```ruby
3904
+ sig <= decoder(<list of expression>).(out0, vals0).(out1, vals1).(..)
3905
+ ```
3906
+
3907
+ In the code above, `out0`, `out1`, and so, on are the signals whose value is to set or reset, and `vals0`, `vals1` are the corresponding sets of values that are compared to the primary arguments. If the values are equal, the corresponding signal is set, and it is reset otherwise. These values have to be given as an array of expressions, one per primary argument, but can be `nil` for indicating a don't care. For example, with the following code:
3908
+
3909
+ ```ruby
3910
+ decoder(a,b,c).(x,[_b010]).(y,[_b110,nil,_b11]).(z,[_b100,_b01,_b11])
3911
+ ```
3912
+
3913
+ `x` will be 1 if `a` is equal to `_b010`, and 0 otherwise; `y` will be 1 if `a` is equal to `_b110` and `c` is equal to `_b11`, and 0 otherwise; and `z` will be 1 if `a` is equal to `_b100`, `b` is equal to `_b01` and c is equal to `_b11`, and 0 otherwise.
3914
+
3915
+ It is also possible to change how the comparisons results are reduced by specifying the operator to use through the last primary argument. For example, the decoder of the previous example can be converted to one which will set the signals if any of the corresponding equalities holds as follows:
3916
+
3917
+ ```ruby
3918
+ decoder(a,b,c,:|).(x,[_b010]).(y,[_b110,nil,_b11]).(z,[_b100,_b01,_b11])
3919
+ ```
3920
+
3921
+ ### Expression Decoder
3922
+
3923
+ The expression decoder is used as an expression and returns a bit-vector. It takes as argument a list of expressions whose first one is compared to each of the others. In case of equality, the corresponding bit of the result is set, otherwise it is reset. For example, with the following code:
3924
+
3925
+ ```ruby
3926
+ sig <= decoder(x,5,8,9)
3927
+ ```
3928
+
3929
+ `sig` will be `_b100` if `x` equals `5`, `_b010` if `x` equals `8`, `_b001` if `x` equals `9`, and `_b000` otherwise.
3930
+
3781
3931
 
3782
3932
  ## FSM
3783
3933
 
@@ -3994,7 +4144,30 @@ Parallel enumerators provide several control methods:
3994
4144
 
3995
4145
  Additionaly, it is possible to exit an enumeration loop using the following command:
3996
4146
 
3997
- * `hbreak`: Exits the current enumeration loop.
4147
+ * `hbreak`: Exits the current enumeration loop, or the current process if present in the top-level `hif` branch of a process when the condition is met. This second usage helps improve the readability of reset conditions, as shown in the following code:
4148
+
4149
+ ```ruby
4150
+ par(clk.posedge) do
4151
+ hif(reset) do
4152
+ <do some reset work>
4153
+ hbreak
4154
+ end
4155
+ <normal execution>
4156
+ end
4157
+ ```
4158
+
4159
+ The code above is equivalent to the following one, but it clearly shows that the reset is an exception.
4160
+
4161
+ ```ruby
4162
+ par(clk.posdege) do
4163
+ hif(reset) do
4164
+ <do some reset work>
4165
+ end
4166
+ helse do
4167
+ <normanl execution>
4168
+ end
4169
+ end
4170
+ ```
3998
4171
 
3999
4172
  __Hardware Implementations of Enumerable Methods__
4000
4173
 
@@ -659,6 +659,28 @@ VALUE rcsim_make_hcase(VALUE mod, VALUE valueV, VALUE defoltV) {
659
659
  return res;
660
660
  }
661
661
 
662
+ /* Creating a hardware casez C object. */
663
+ VALUE rcsim_make_hcasez(VALUE mod, VALUE valueV, VALUE defoltV) {
664
+ // printf("rcsim_make_hcasez\n");
665
+ /* Allocates the hardware case. */
666
+ HCaseZ hcasez = (HCaseZ)malloc(sizeof(HCaseZS));
667
+ // printf("hcasez=%p\n",hcasez);
668
+ /* Set it up. */
669
+ hcasez->kind = HCASEZ;
670
+ hcasez->owner = NULL;
671
+ value_to_rcsim(ExpressionS,valueV,hcasez->value);
672
+ hcasez->num_whens = 0;
673
+ hcasez->matches = NULL;
674
+ hcasez->stmnts = NULL;
675
+ if (TYPE(defoltV) == T_NIL)
676
+ hcasez->defolt = NULL;
677
+ else
678
+ value_to_rcsim(StatementS,defoltV,hcasez->defolt);
679
+ /* Returns the C hardware case embedded into a ruby VALUE. */
680
+ VALUE res;
681
+ rcsim_to_value(HCaseZS,hcasez,res);
682
+ return res;
683
+ }
662
684
 
663
685
  /* Creating a block C object. */
664
686
  VALUE rcsim_make_block(VALUE mod, VALUE modeV) {
@@ -1927,6 +1949,7 @@ void Init_hruby_sim() {
1927
1949
  rb_define_singleton_method(mod,"rcsim_make_timeTerminate",rcsim_make_timeTerminate,0);
1928
1950
  rb_define_singleton_method(mod,"rcsim_make_hif",rcsim_make_hif,3);
1929
1951
  rb_define_singleton_method(mod,"rcsim_make_hcase",rcsim_make_hcase,2);
1952
+ rb_define_singleton_method(mod,"rcsim_make_hcasez",rcsim_make_hcasez,2);
1930
1953
  rb_define_singleton_method(mod,"rcsim_make_block",rcsim_make_block,1);
1931
1954
  rb_define_singleton_method(mod,"rcsim_make_value_numeric",rcsim_make_value_numeric,2);
1932
1955
  rb_define_singleton_method(mod,"rcsim_make_value_numeric_63one",rcsim_make_value_numeric_63one,2);
@@ -27,6 +27,7 @@ typedef struct TransmitS_ TransmitS;
27
27
  typedef struct PrintS_ PrintS;
28
28
  typedef struct HIfS_ HIfS;
29
29
  typedef struct HCaseS_ HCaseS;
30
+ typedef struct HCaseZS_ HCaseZS;
30
31
  typedef struct TimeWaitS_ TimeWaitS;
31
32
  typedef struct TimeRepeatS_ TimeRepeatS;
32
33
  typedef struct TimeTerminateS_ TimeTerminateS;
@@ -63,6 +64,7 @@ typedef struct TransmitS_* Transmit;
63
64
  typedef struct PrintS_* Print;
64
65
  typedef struct HIfS_* HIf;
65
66
  typedef struct HCaseS_* HCase;
67
+ typedef struct HCaseZS_* HCaseZ;
66
68
  typedef struct TimeWaitS_* TimeWait;
67
69
  typedef struct TimeRepeatS_* TimeRepeat;
68
70
  typedef struct TimeTerminateS_* TimeTerminate;
@@ -91,7 +93,7 @@ typedef enum {
91
93
  #endif
92
94
  OBJECT, SYSTEMT, SIGNALI, SCOPE, BEHAVIOR, SYSTEMI, CODE, BLOCK, EVENT,
93
95
  #ifdef RCSIM
94
- /* Statements */ TRANSMIT, PRINT, HIF, HCASE,
96
+ /* Statements */ TRANSMIT, PRINT, HIF, HCASE, HCASEZ,
95
97
  TIME_WAIT, TIME_REPEAT, TIME_TERMINATE,
96
98
  /* Expressions */ UNARY, BINARY, SELECT, CONCAT, CAST,
97
99
  /* References */ REF_OBJECT, REF_INDEX, REF_RANGE, REF_CONCAT,
@@ -300,6 +302,13 @@ Value shift_right_value(Value src0, Value src1, Value dst);
300
302
  * @return dst */
301
303
  extern Value equal_value(Value src0, Value src1, Value dst);
302
304
 
305
+ /** Computes the equal (NXOR) of two values treating Z as wildcards.
306
+ * @param src0 the first source value of the comparison
307
+ * @param src1 the second source value of the comparison
308
+ * @param dst the destination value
309
+ * @return dst */
310
+ extern Value equal_value_z(Value src0, Value src1, Value dst);
311
+
303
312
  /** Computes the C equal of two general values.
304
313
  * @param src0 the first source value of the addition
305
314
  * @param src1 the second source value of the addition
@@ -307,6 +316,13 @@ extern Value equal_value(Value src0, Value src1, Value dst);
307
316
  * @return the destination value */
308
317
  extern Value equal_value_c(Value src0, Value src1, Value dst);
309
318
 
319
+ /** Computes the C equal of two general values treating Z as wildcards.
320
+ * @param src0 the first source value of the addition
321
+ * @param src1 the second source value of the addition
322
+ * @param dst the destination value
323
+ * @return the destination value */
324
+ extern Value equal_value_z_c(Value src0, Value src1, Value dst);
325
+
310
326
  /** Computes the C not equal of two general values.
311
327
  * @param src0 the first source value of the addition
312
328
  * @param src1 the second source value of the addition
@@ -701,6 +717,18 @@ typedef struct HCaseS_ {
701
717
  Statement defolt; /* The default statement. */
702
718
  } HCaseS;
703
719
 
720
+ /** The C model of a hardware casez statement. */
721
+ typedef struct HCaseZS_ {
722
+ Kind kind; /* The kind of object. */
723
+ Object owner; /* The owner of the object if any. */
724
+
725
+ Expression value; /* The value to match. */
726
+ int num_whens; /* The number of possible cases. */
727
+ Expression* matches;/* The cases matching values. */
728
+ Statement* stmnts; /* The corresponding statements. */
729
+ Statement defolt; /* The default statement. */
730
+ } HCaseZS;
731
+
704
732
  /** The C model of a time wait statement. */
705
733
  typedef struct TimeWaitS_ {
706
734
  Kind kind; /* The kind of object. */
@@ -1733,44 +1733,44 @@ static Value shift_right_value_bitstring(Value src0, Value src1, Value dst) {
1733
1733
  }
1734
1734
 
1735
1735
 
1736
- /** Computes the equal (!XOR) of two bitstring values.
1736
+ /** computes the equal (!xor) of two bitstring values.
1737
1737
  * @param src0 the first source value of the and
1738
1738
  * @param src1 the second source value of the and
1739
1739
  * @param dst the destination value
1740
1740
  * @return dst */
1741
1741
  static Value equal_value_bitstring(Value src0, Value src1, Value dst) {
1742
1742
  // printf("equal_value_bitstring.\n");
1743
- /* Compute the width of sources in bits. */
1743
+ /* compute the width of sources in bits. */
1744
1744
  unsigned long long width0 = type_width(src0->type);
1745
1745
  unsigned long long width1 = type_width(src1->type);
1746
1746
 
1747
- /* Update the destination capacity if required. */
1747
+ /* update the destination capacity if required. */
1748
1748
  resize_value(dst,width0);
1749
- /* Set the type and size of the destination from the type of the source.*/
1749
+ /* set the type and size of the destination from the type of the source.*/
1750
1750
  dst->type = src0->type;
1751
1751
  dst->numeric = 0;
1752
1752
 
1753
- /* Get access to the data of the sources. */
1753
+ /* get access to the data of the sources. */
1754
1754
  char *src0_data = src0->data_str;
1755
1755
  char *src1_data = src1->data_str;
1756
- /* Get access to the data of the destination. */
1756
+ /* get access to the data of the destination. */
1757
1757
  char *dst_data = dst->data_str;
1758
1758
 
1759
- /* Get the sign extension character of source 1 and convert it to a bit.*/
1759
+ /* get the sign extension character of source 1 and convert it to a bit.*/
1760
1760
  int ext = bitstring_ext(src1);
1761
1761
 
1762
- /* Perform the !xor. */
1762
+ /* perform the !xor. */
1763
1763
  unsigned long long count;
1764
- /* Check if values are the same. */
1764
+ /* check if values are the same. */
1765
1765
  char same = '1';
1766
1766
  for(count = 0; count < width0; ++count) {
1767
- char d0 = src0_data[count] - '0'; /* Get and convert to bit. */
1767
+ char d0 = src0_data[count] - '0'; /* get and convert to bit. */
1768
1768
  char d1;
1769
1769
  if (count < width1) {
1770
- /* Still within source 1. */
1771
- d1 = src1_data[count] - '0';/* Get and convert to bit. */
1770
+ /* still within source 1. */
1771
+ d1 = src1_data[count] - '0';/* get and convert to bit. */
1772
1772
  } else {
1773
- /* Outside source 1, use the sign extension. */
1773
+ /* outside source 1, use the sign extension. */
1774
1774
  d1 = ext;
1775
1775
  }
1776
1776
  if (d0 == (d0&1)) {
@@ -1782,22 +1782,98 @@ static Value equal_value_bitstring(Value src0, Value src1, Value dst) {
1782
1782
  break;
1783
1783
  }
1784
1784
  } else {
1785
- /* Undefined. */
1785
+ /* undefined. */
1786
1786
  same = 'x';
1787
1787
  break;
1788
1788
  }
1789
1789
  } else {
1790
- /* Undefined. */
1790
+ /* undefined. */
1791
1791
  same = 'x';
1792
1792
  break;
1793
1793
  }
1794
1794
  }
1795
- /* Set the destination to 0 or 1 depending of different. */
1795
+ /* set the destination to 0 or 1 depending of different. */
1796
1796
  dst_data[0] = same;
1797
1797
  for(count = 1; count < width0; ++count) {
1798
1798
  dst_data[count] = '0';
1799
1799
  }
1800
- /* Return the destination. */
1800
+ /* return the destination. */
1801
+ return dst;
1802
+ }
1803
+
1804
+ /** computes the equal (!xor) of two bitstring values treating Z as wildcard.
1805
+ * @param src0 the first source value of the and
1806
+ * @param src1 the second source value of the and
1807
+ * @param dst the destination value
1808
+ * @return dst */
1809
+ static Value equal_value_z_bitstring(Value src0, Value src1, Value dst) {
1810
+ // printf("equal_value_bitstring.\n");
1811
+ /* compute the width of sources in bits. */
1812
+ unsigned long long width0 = type_width(src0->type);
1813
+ unsigned long long width1 = type_width(src1->type);
1814
+
1815
+ /* update the destination capacity if required. */
1816
+ resize_value(dst,width0);
1817
+ /* set the type and size of the destination from the type of the source.*/
1818
+ dst->type = src0->type;
1819
+ dst->numeric = 0;
1820
+
1821
+ /* get access to the data of the sources. */
1822
+ char *src0_data = src0->data_str;
1823
+ char *src1_data = src1->data_str;
1824
+ /* get access to the data of the destination. */
1825
+ char *dst_data = dst->data_str;
1826
+
1827
+ /* get the sign extension character of source 1 and convert it to a bit.*/
1828
+ int ext = bitstring_ext(src1);
1829
+
1830
+ /* perform the !xor. */
1831
+ unsigned long long count;
1832
+ /* check if values are the same. */
1833
+ char same = '1';
1834
+ for(count = 0; count < width0; ++count) {
1835
+ char d0 = src0_data[count] - '0'; /* get and convert to bit. */
1836
+ char d1;
1837
+ if (d0 == 'z' - '0' || d0 == 'Z' - '0') {
1838
+ /* Z is wildcard, so same. */
1839
+ continue;
1840
+ }
1841
+ if (count < width1) {
1842
+ /* still within source 1. */
1843
+ d1 = src1_data[count] - '0';/* get and convert to bit. */
1844
+ } else {
1845
+ /* outside source 1, use the sign extension. */
1846
+ d1 = ext;
1847
+ }
1848
+ if (d1 == 'z' - '0' || d1 == 'Z' - '0') {
1849
+ /* Z is wildcard, so same. */
1850
+ continue;
1851
+ }
1852
+ if (d0 == (d0&1)) {
1853
+ /* d0 is defined. */
1854
+ if (d1 == (d1&1)) {
1855
+ /* d1 is also defined. */
1856
+ if (d0 != d1) {
1857
+ same = '0';
1858
+ break;
1859
+ }
1860
+ } else {
1861
+ /* undefined. */
1862
+ same = 'x';
1863
+ break;
1864
+ }
1865
+ } else {
1866
+ /* undefined. */
1867
+ same = 'x';
1868
+ break;
1869
+ }
1870
+ }
1871
+ /* set the destination to 0 or 1 depending of different. */
1872
+ dst_data[0] = same;
1873
+ for(count = 1; count < width0; ++count) {
1874
+ dst_data[count] = '0';
1875
+ }
1876
+ /* return the destination. */
1801
1877
  return dst;
1802
1878
  }
1803
1879
 
@@ -3299,7 +3375,7 @@ Value shift_right_value(Value src0, Value src1, Value dst) {
3299
3375
  }
3300
3376
 
3301
3377
 
3302
- /** Computes the equal (!XOR) of two general values.
3378
+ /** Computes the equal (NXOR) of two general values.
3303
3379
  * @param src0 the first source value of the addition
3304
3380
  * @param src1 the second source value of the addition
3305
3381
  * @param dst the destination value
@@ -3336,6 +3412,43 @@ Value equal_value(Value src0, Value src1, Value dst) {
3336
3412
  return dst;
3337
3413
  }
3338
3414
 
3415
+ /** Computes the equal (NXOR) of two general values.
3416
+ * @param src0 the first source value of the addition
3417
+ * @param src1 the second source value of the addition
3418
+ * @param dst the destination value
3419
+ * @return the destination value */
3420
+ Value equal_value_z(Value src0, Value src1, Value dst) {
3421
+ // printf("equal_value.\n");
3422
+ /* Might allocate a new value so save the current pool state. */
3423
+ unsigned int pos = get_value_pos();
3424
+ /* Do a numeric computation if possible, otherwise fallback to bitstring
3425
+ * computation. */
3426
+ if (src0->numeric) {
3427
+ if (src1->numeric) {
3428
+ // printf("numeric numeric\n");
3429
+ /* Both sources are numeric. */
3430
+ return equal_value_numeric(src0,src1,dst);
3431
+ } else {
3432
+ // printf("numeric bitstring\n");
3433
+ /* src1 is not numeric, convert src0 to bitstring. */
3434
+ src0 = set_bitstring_value(src0,get_value());
3435
+ }
3436
+ } else {
3437
+ /* src0 is not numeric, what about src1. */
3438
+ if (src1->numeric) {
3439
+ // printf("bitstring numeric\n");
3440
+ /* src1 is numeric, convert it to bitstring. */
3441
+ src1 = set_bitstring_value(src1,get_value());
3442
+ }
3443
+ }
3444
+ /* The sources cannot be numeric, compute bitsitrings. */
3445
+ dst = equal_value_z_bitstring(src0,src1,dst);
3446
+ /* Restores the pool of values. */
3447
+ set_value_pos(pos);
3448
+ /* Return the destination. */
3449
+ return dst;
3450
+ }
3451
+
3339
3452
 
3340
3453
  /** Computes the C equal of two general values.
3341
3454
  * @param src0 the first source value of the addition
@@ -3347,6 +3460,16 @@ Value equal_value_c(Value src0, Value src1, Value dst) {
3347
3460
  return reduce_or_value(dst,dst);
3348
3461
  }
3349
3462
 
3463
+ /** Computes the C equal of two general values treating Z as wildcards.
3464
+ * @param src0 the first source value of the addition
3465
+ * @param src1 the second source value of the addition
3466
+ * @param dst the destination value
3467
+ * @return the destination value */
3468
+ Value equal_value_z_c(Value src0, Value src1, Value dst) {
3469
+ dst = equal_value_z(src0,src1,dst);
3470
+ return reduce_or_value(dst,dst);
3471
+ }
3472
+
3350
3473
 
3351
3474
  /** Computes the C not equal of two general values.
3352
3475
  * @param src0 the first source value of the addition