Signed Arithmetic in Verilog 2001 – Opportunities and Hazards
Dr. Greg Tumbush, Starkey Labs, Colorado Springs, CO
Introduction
Starkey Labs is in the business of designing and
manufacturing hearing aids. The new digital hearings aids
we design at the Starkey Labs Colorado IC Design Center
utilize very complex DSP algorithms implemented in both
software and hardware accelerators. The predominant data
type used in these algorithms is signed. The format of the
signed type is two’s complement. The designation of signed
and two’s complement is used interchangeably throughout
this document.
Verilog 2001 provides a very rich set of new signed
data types. However, there are issues when performing
operations such as sign extension, truncation or rounding,
saturation, addition, and multiplication with signed values.
These new data types (in theory) free the designer from
worrying about some of these signed data type issues. More
compact and readable code should result. However, in the
spirit of Verilog, usage of this new functionality is “user
beware”! Arithmetic manipulation between mixes of signed
and unsigned may simulate and synthesize in unintended
ways. Assignments between differently sized types may also
not result in what the designer intended. Does the usage of
signed data types in arithmetic operations result in smaller or
larger circuits?
Verilog 1995 provides only one signed data type,
integer. The rule is that if any operand in an expression is
unsigned the operation is considered to be unsigned. The
rule still applies for Verilog 2001 but now all regs, wires,
and ports can be signed. In addition, a numeric value can be
designated with a ‘s similar to the ‘h hex designation.
Signed functions are also supported as well as the type
casting operators $signed and $unsigned. There are many
new rules about when an operation is unsigned, and some
may surprise you!
In this paper I will provide code examples of how the
new signed data types can be used to create more compact
code if some simple rules are followed. RTL and gate level
simulation results of add and multiply operations using
mixtures of signed and unsigned data types will be provided.
Area results from synthesis using Design Compiler 2003.12
will be presented to compare efficiencies of these
operations. Synthesis warnings that should be investigated
thoroughly will be explained. Suggestions for improvement
in the Verilog 2001 language, such as saturation support,
will also be provided.
Signed Data Types
Table 1 demonstrates the conversion of a decimal value to
a signed 3-bit value in 2’s complement format. A 3-bit signed
value would be declared using Verilog 2001 as signed [2:0]
A;.
Decimal Value Signed Representation
3 3’b011
2 3’b010
1 3’b001
0 3’b000
-1 3’b111
-2 3’b110
-3 3’b101
-4 3’b100
Table 1: Decimal to 3-bit Signed
Type Casting
The casting operators, $unsigned and $signed, only
have effect when casting a smaller bit width to a larger bit.
Casting using $unsigned(signal_name) will zero fill the
input. For example A = $unsigned(B) will zero fill B and
assign it to A. Casting using $signed(signal_name) will
sign extend the input. For example, A = $signed(B). If the
sign bit is X or Z the value will be sign extended using X or
Z, respectively. Assigning to a smaller bit width signal will
simply truncate the necessary MSB’s as usual. Casting to
the same bit width will have no effect other than to remove
synthesis warnings.
Signed Based Values
The only way to declare a signed value in Verilog 1995
was to declare it as an integer which limited the size of the
value to 32-bits only[1]. Verilog 2001 provides the ‘s
construct for declaring and specifying a sized value as
signed. For example, 2 represented as a 3-bit signed hex
value would be specified as 3’sh2. Somewhat confusing is
specifying negative signed values. The value -4 represented
as a 3-bit signed hex value would be specified as -3’sh4. A
decimal number is always signed.
Signed Addition
Adding two values that are n-bits wide will produce a
n+1 bit wide result. The signed values must be sign