Types, Widths, and Signed Values
Use logic, 2-state and 4-state types, sized literals, and conversions without surprises.
Four states or two states
logic is a 4-state type. In addition to 0 and 1, it can hold X for an unknown value and Z for high impedance. These states help simulation expose missing initialization, conflicting drivers, or an undriven bus.
bit is limited to 0 and 1. SystemVerilog also provides integer types with different widths and state models. In RTL, logic is usually the clearest choice for ports and internal signals.
logic valid;
logic [15:0] data;
bit enable_model;
int unsigned transaction_count;A 2-state type can speed up some test models, but it converts an unknown value to 0. Do not use it where that conversion could hide an initialization error.
Width is part of the operation
A value must be wide enough before an operation takes place. Two 8-bit operands do not automatically provide a useful ninth result bit at the destination.
module add_with_carry (
input logic [7:0] i_a,
input logic [7:0] i_b,
output logic [8:0] o_sum
);
always_comb begin
o_sum = {1'b0, i_a} + {1'b0, i_b};
end
endmoduleThe explicit extension preserves carry and records the design choice. Literals such as 8'hA5, 5'd17, or 16'sd-3 state their width, base, and sign.
'0 fills the entire destination with zeros, while '1 fills it with ones. This notation follows the destination width and works well for generic resets.
Signed and unsigned
A logic [7:0] vector is unsigned by default. The signed keyword changes comparisons, extensions, and arithmetic shifts.
logic signed [11:0] sample;
logic signed [12:0] extended;
assign extended = $signed({sample[11], sample});Mixing signed and unsigned operands in one expression can produce an unexpected interpretation. Give signals a type that matches their meaning, then use $signed, $unsigned, or a type cast at the exact conversion point.
Casts and checks
A static cast uses type'(expression). It makes a conversion visible during review.
typedef logic signed [15:0] sample_t;
sample_t filtered;
assign filtered = sample_t'(raw_value);A cast does not prevent truncation. If the destination is narrower, upper bits are discarded. Check bounds, compiler warnings, and boundary values in the testbench.
Key points
logicpreservesXandZ, which helps debugging.- A 2-state type can hide an unknown value.
- Operand width must be correct before the operation.
- Signedness affects comparisons, extensions, and shifts.
- An explicit cast documents a conversion but cannot prevent truncation.
📝 Test your knowledge - Chapter quiz