Vl-constint
Representation for constant integer literals with no X or Z bits,
e.g., 42, 5'b1, etc.
This is a product type, introduced by deftagsum in support of vl-value.
Fields
- origwidth — posp
- Subtle; generally should not be used; see below.
- value — natp
- The most important part of a constant integer. Even
immediately upon parsing the value has already been determined
and is available to you as an ordinary natural number.
- origsign — vl-exprsign-p
- Subtle; generally should not be used; see below.
- wasunsized — booleanp
- Set to t by the parser for unsized constants like 5
and 'b0101, but not for sized ones like 4'b0101.
Additional Requirements
The following invariant is enforced on the fields:
(unsigned-byte-p origwidth value)
Detailed Explanation
Constant integers are produced from source code constructs like
5, 4'b0010, and 3'h0.
Note that the value of a constant integer is never negative. In
Verilog there are no negative literals; instead, an expression like
-5 is basically parsed the same as -(5), so the negative
sign is not part of the literal. See Section 3.5.1 of the
Verilog-2005 standard.
The origwidth and origsign fields are subtle and you
usually should not be looking at the origwidth and
origsign of an expression unless you have really studied how
sizing works in and you really know what you are doing.
These fields indicate the original width and signedness of
the literal as specified in the source code. For instance, if the
source code contains 8'sd 65, then we will get a value whose
origwidth is 8 and whose origsign is :vl-signed.
However, in general, the process for sizing Verilog
expressions can effectively ``change'' the widths and types of the
operands within that expression. For instance, if a and b
are unsigned 10-bit wires and we have:
assign a = b + 3'sb1;
Then even though 3'sb1 looks like a signed 3-bit integer, the
sizing process will convert it into a 10-bit unsigned number! The
takeaway: you can't really rely on the original size and signedness
to tell you the real story, so unless you're implementing the sizing
algorithm you should probably avoid them.
We insist that 0 <= value <= 2^origwidth for every constant
integer. If our lexer encounters something ill-formed like
3'b 1111, it emits a warning and truncates the value to the
specified width as required by Section 3.5.1 (page 10) of the
Verilog-2005 standard and Section 5.7.1 (page 37) of the
SystemVerilog standard.
Note that in Verilog, unsized integer constants like 5 or
'b101 have an implementation-dependent size of at least 32 bits.
Early versions of VL tried to treat such numbers in an abstract way,
saying they had "integer size". But we eventually decided that
this was too error-prone and we now instead act like a 32-bit
implementation even at the level of our lexer. This conveniently
makes the width of a constant integer just a positive number.
There is some risk to this. Certain expressions may produce
different results on 32-bit versus, say, 64-bit implementations.
Because of this, we added the wasunsized field so that we might,
some day, statically check for problematic uses of unsized
constants.
All constints are automatically created with hons. This is
probably pretty trivial, but it seems nice. For instance, the
constant integers from 0-32 are probably used thousands of times
throughout a design for bit-selects and wire ranges, so sharing their
memory may be useful.
Subtopics
- Make-vl-constint
- Basic constructor macro for vl-constint structures.
- Vl-constint->value
- Get the value field from a vl-constint.
- Vl-constint->wasunsized
- Get the wasunsized field from a vl-constint.
- Vl-constint->origwidth
- Get the origwidth field from a vl-constint.
- Vl-constint->origsign
- Get the origsign field from a vl-constint.
- Change-vl-constint
- Modifying constructor for vl-constint structures.