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 +4 -4
- data/README.md +182 -9
- data/ext/hruby_sim/hruby_rcsim_build.c +23 -0
- data/ext/hruby_sim/hruby_sim.h +29 -1
- data/ext/hruby_sim/hruby_sim_calc.c +141 -18
- data/ext/hruby_sim/hruby_sim_tree_calc.c +37 -0
- data/lib/HDLRuby/hdr_samples/case_bench.rb +1 -1
- data/lib/HDLRuby/hdr_samples/logic_bench.rb +12 -12
- data/lib/HDLRuby/hdr_samples/with_assign_to_slice.rb +19 -0
- data/lib/HDLRuby/hdr_samples/with_auto_connect.rb +40 -0
- data/lib/HDLRuby/hdr_samples/with_casez.rb +35 -0
- data/lib/HDLRuby/hdr_samples/with_expr_decoder.rb +38 -0
- data/lib/HDLRuby/hdr_samples/with_expr_hif.rb +34 -0
- data/lib/HDLRuby/hdr_samples/with_hbreak.rb +42 -0
- data/lib/HDLRuby/hdr_samples/with_henumerable.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_values.rb +3 -0
- data/lib/HDLRuby/hruby_high.rb +237 -15
- data/lib/HDLRuby/hruby_low.rb +50 -46
- data/lib/HDLRuby/hruby_rcsim.rb +7 -2
- data/lib/HDLRuby/hruby_verilog.rb +17 -6
- data/lib/HDLRuby/std/decoder.rb +77 -2
- data/lib/HDLRuby/std/hruby_enum.rb +103 -0
- data/lib/HDLRuby/verilog_hruby.rb +30 -0
- data/lib/HDLRuby/verilog_parser.rb +1 -1
- data/lib/HDLRuby/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d8c62653a5b0c4fa2e8a42e0c1198d3a0e714be890e4caf80058532150117b51
|
|
4
|
+
data.tar.gz: 6ec87f18f390bebb88d19bffce01a6ab7420d9f82777685d4ec330d0b5f2be34
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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 (`
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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);
|
data/ext/hruby_sim/hruby_sim.h
CHANGED
|
@@ -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
|
-
/**
|
|
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
|
-
/*
|
|
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
|
-
/*
|
|
1747
|
+
/* update the destination capacity if required. */
|
|
1748
1748
|
resize_value(dst,width0);
|
|
1749
|
-
/*
|
|
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
|
-
/*
|
|
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
|
-
/*
|
|
1756
|
+
/* get access to the data of the destination. */
|
|
1757
1757
|
char *dst_data = dst->data_str;
|
|
1758
1758
|
|
|
1759
|
-
/*
|
|
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
|
-
/*
|
|
1762
|
+
/* perform the !xor. */
|
|
1763
1763
|
unsigned long long count;
|
|
1764
|
-
/*
|
|
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'; /*
|
|
1767
|
+
char d0 = src0_data[count] - '0'; /* get and convert to bit. */
|
|
1768
1768
|
char d1;
|
|
1769
1769
|
if (count < width1) {
|
|
1770
|
-
/*
|
|
1771
|
-
d1 = src1_data[count] - '0';/*
|
|
1770
|
+
/* still within source 1. */
|
|
1771
|
+
d1 = src1_data[count] - '0';/* get and convert to bit. */
|
|
1772
1772
|
} else {
|
|
1773
|
-
/*
|
|
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
|
-
/*
|
|
1785
|
+
/* undefined. */
|
|
1786
1786
|
same = 'x';
|
|
1787
1787
|
break;
|
|
1788
1788
|
}
|
|
1789
1789
|
} else {
|
|
1790
|
-
/*
|
|
1790
|
+
/* undefined. */
|
|
1791
1791
|
same = 'x';
|
|
1792
1792
|
break;
|
|
1793
1793
|
}
|
|
1794
1794
|
}
|
|
1795
|
-
/*
|
|
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
|
-
/*
|
|
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 (
|
|
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
|