Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Support] Add FVInt, a four-valued arbitrary precision integer (#7422)
Add the `FVInt` class to CIRCT's support library. This class can represent arbitrary precision integers where each bit can be one of the four values 0, 1, X, and Z. The name intends to suggest a *four-valued APInt*, with the option to also introduce a *nine-valued NVInt* in the future. Internally, `FVInt` uses two `APInt`s to store its data: `value` stores whether a bit is 0/X or 1/Z, and `unknown` stores whether a bit is known (0 or 1) or unknown (X or Z). Together they allocate 2 bits of storage for each of the `FVInt`'s digits, which allows for four different values per digit. This representation as `value` and `unknown` makes many of the logical and arithmetic operations pretty straightforward to implement. Most four-valued operations can be trivially implemented by performing the equivalent two-valued operation on `value`, and then accounting for X and Z bits through a few logic operations on `unknown`. Note that Slang defines its own version of this (`SVInt`). But since Slang is an optional dependency of CIRCT, it makes sense to have a CIRCT equivalent that is built around LLVM's `APInt`, for use in our dialects. This first version of `FVInt` has a rather incomplete set of operations, but it covers basic AND, OR, XOR, NOT, negation, addition, subtraction, and multiplication as a proof-of-concept. The remaining operations will be added in future commits. We are also going to need a four-valued equivalent of `IntegerAttr` based on `FVInt`. This commit is motivated by the Slang frontend, which now supports enough of SystemVerilog to make some test designs start to hit the lack of number literals with X and Z.
- Loading branch information