## Arithmetic Operations

XST supports the following arithmetic operations:

Adders, Subtractors, Comparators and Multipliers are supported for signed and unsigned operations.

Please refer to the "Signed/Unsigned Support" section of this chapter for more information on the signed/unsigned operations support in VHDL.

Moreover, XST performs resource sharing for adders, subtractors, adders/subtractors and multipliers.

## Adders, Subtractors, Adders/Subtractors

This section provides HDL examples of adders and subtractors

## Log File

The XST log file reports the type and size of recognized adder, subtractor and adder/subtractor during the macro recognition step:

Related source file is arithmetic_operations_1.vhd.

Found 8-bit adder for signal <sum>.

## Unsigned 8-bit Adder

This subsection contains a VHDL and Verilog description of an unsigned 8-bit Adder

The following table shows pin descriptions for an unsigned 8-bit Adder.

A[7:0], B[7:0] Add Operands SUM[7:0] Add Result## VHDL

Following is the VHDL code for an unsigned 8-bit Adder.

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity adder is port(A,B : in std_logic_vector(7 downto 0); SUM : out std_logic_vector(7 downto 0)); end adder; architecture archi of adder is begin SUM <= A + B; end archi;## Verilog

Following is the Verilog code for an unsigned 8-bit Adder.

module adder(A, B, SUM); input [7:0] A; input [7:0] B; output [7:0] SUM; assign SUM = A + B; endmodule## Unsigned 8-bit Adder with Carry In

This section contains VHDL and Verilog descriptions of an unsigned 8-bit adder with Carry In.

The following table shows pin descriptions for an unsigned 8-bit adder with carry.

A[7:0], B[7:0] Add Operands CI Carry In SUM[7:0] Add Result## VHDL

Following is the VHDL code for an unsigned 8-bit adder with carry in.

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity adder is port(A,B : in std_logic_vector(7 downto 0); CI : in std_logic; SUM : out std_logic_vector(7 downto 0)); end adder; architecture archi of adder is begin SUM <= A + B + CI; end archi;## Verilog

Following is the Verilog code for an unsigned 8-bit adder with carry in.

module adder(A, B, CI, SUM); input [7:0] A; input [7:0] B; input CI; output [7:0] SUM; assign SUM = A + B + CI; endmodule## Unsigned 8-bit Adder with Carry Out

This section contains VHDL and Verilog descriptions of an unsigned 8-bit adder with Carry Out.

If you use VHDL, then before writing a "+" operation with Carry Out, please examine the arithmetic package you are going to use. For example "std_logic_unsigned" does not allow you to write "+" in the following form to obtain Carry Out:

Res(9-bit) = A(8-bit) + B(8-bit)The reason is that the size of the result for "+" in this package is equal to the size of the longest argument, that is, 8 bit.

- One solution, for the example, is to adjust the size of operands A and B to 9-bit using concatenation
In this case, XST recognizes that this 9-bit adder can be implemented as an 8-bit adder with Carry Out.

- Another solution is to convert A and B to integers and then convert the result back to the std_logic vector, specifying the size of the vector equal to 9:
The following table shows pin descriptions for an unsigned 8-bit adder with carry

A[7:0], B[7:0] Add Operands SUM[7:0] Add Result CO Carry Out## VHDL

Following is the VHDL code for an unsigned 8-bit adder with carry out.

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity adder is port(A,B : in std_logic_vector(7 downto 0); SUM : out std_logic_vector(7 downto 0); CO : out std_logic); end adder; architecture archi of adder is signal tmp: std_logic_vector(8 downto 0); begin tmp <= conv_std_logic_vector( (conv_integer(A) + conv_integer(B)),9); SUM <= tmp(7 downto 0); CO <= tmp(8); end archi;In the preceding example, two arithmetic packages are used:

- std_logic_arith. This package contains the integer to std_logic conversion function, that is, conv_std_logic_vector.
- std_logic_unsigned. This package contains the unsigned "+" operation.
## Verilog

Following is the Verilog code for an unsigned 8-bit adder with carry out.

module adder(A, B, SUM, CO); input [7:0] A; input [7:0] B; output [7:0] SUM; output CO; wire [8:0] tmp; assign tmp = A + B; assign SUM = tmp [7:0]; assign CO = tmp [8]; endmodule## Unsigned 8-bit Adder with Carry In and Carry Out

This section contains VHDL and Verilog code for an unsigned 8-bit adder with Carry In and Carry Out.

The following table shows pin descriptions for an unsigned 8-bit adder with carry.

A[7:0], B[7:0] Add Operands CI Carry In SUM[7:0] Add Result CO Carry Out## VHDL

Following is the VHDL code for an unsigned 8-bit adder with carry in and carry out.

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity adder is port(A,B : in std_logic_vector(7 downto 0); CI : in std_logic; SUM : out std_logic_vector(7 downto 0); CO : out std_logic); end adder; architecture archi of adder is signal tmp: std_logic_vector(8 downto 0); begin tmp <= conv_std_logic_vector( (conv_integer(A) + conv_integer(B) + conv_integer(CI)),9); SUM <= tmp(7 downto 0); CO <= tmp(8); end archi;## Verilog

Following is the Verilog code for an unsigned 8-bit adder with carry in and carry out.

module adder(A, B, CI, SUM, CO); input CI; input [7:0] A; input [7:0] B; output [7:0] SUM; output CO; wire [8:0] tmp; assign tmp = A + B + CI; assign SUM = tmp [7:0]; assign CO = tmp [8]; endmodule## Simple Signed 8-bit Adder

The following table shows pin descriptions for a simple signed 8-bit adder.

A[7:0], B[7:0] Add Operands SUM[7:0] Add Result## VHDL

Following is the VHDL code for a simple signed 8-bit adder.

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_signed.all; entity adder is port(A,B : in std_logic_vector(7 downto 0); SUM : out std_logic_vector(7 downto 0)); end adder; architecture archi of adder is begin SUM <= A + B; end archi;## Verilog

There is no equivalent Verilog code, as Verilog does not support signed values.

## Unsigned 8-bit Subtractor

The following table shows pin descriptions for an unsigned 8-bit subtractor.

A[7:0], B[7:0] Sub Operands RES[7:0] Sub Result## VHDL

Following is the VHDL code for an unsigned 8-bit subtractor.

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity subtr is port(A,B : in std_logic_vector(7 downto 0); RES : out std_logic_vector(7 downto 0)); end subtr; architecture archi of subtr is begin RES <= A - B; end archi;## Verilog

Following is the Verilog code for an unsigned 8-bit subtractor.

module subtr(A, B, RES); input [7:0] A; input [7:0] B; output [7:0] RES; assign RES = A - B; endmodule## Unsigned 8-bit Adder/Subtractor

The following table shows pin descriptions for an unsigned 8-bit adder/subtractor.

A[7:0], B[7:0] Add/Sub Operands OPER Add/Sub Select SUM[7:0] Add/Sub Result## VHDL

Following is the VHDL code for an unsigned 8-bit adder/subtractor.

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity addsub is port(A,B : in std_logic_vector(7 downto 0); OPER: in std_logic; RES : out std_logic_vector(7 downto 0)); end addsub; architecture archi of addsub is begin RES <= A + B when OPER='0' else A - B; end archi;## Verilog

Following is the Verilog code for an unsigned 8-bit adder/subtractor.

module addsub(A, B, OPER, RES); input OPER; input [7:0] A; input [7:0] B; output [7:0] RES; reg [7:0] RES; always @(A or B or OPER) begin if (OPER==1'b0) RES = A + B; else RES = A - B; end endmodule## Comparators (=, /=,<, <=, >, >=)

This section contains a VHDL and Verilog description for an unsigned 8-bit greater or equal comparator.

## Log File

The XST log file reports the type and size of recognized comparators during the macro recognition step:

Related source file is comparators_1.vhd.

Found 8-bit comparator greatequal for signal <$n0000> created at line 10.

8-bit comparator greatequal : 1

## Unsigned 8-bit Greater or Equal Comparator

The following table shows pin descriptions for a comparator.

A[7:0], B[7:0] Add/Sub Operands CMP Comparison Result## VHDL

Following is the VHDL code for an unsigned 8-bit greater or equal comparator.

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity compar is port(A,B : in std_logic_vector(7 downto 0); CMP : out std_logic); end compar; architecture archi of compar is begin CMP <= '1' when A >= B else '0'; end archi;## Verilog

Following is the Verilog code for an unsigned 8-bit greater or equal comparator.

module compar(A, B, CMP); input [7:0] A; input [7:0] B; output CMP; assign CMP = A >= B ? 1'b1 : 1'b0; endmodule## Multipliers

When implementing a multiplier, the size of the resulting signal is equal to the sum of 2 operand lengths. If you multiply A (8-bit signal) by B (4-bit signal), then the size of the result must be declared as a 12-bit signal.

## Large Multipliers Using Block Multipliers

XST can generate large multipliers using an 18x18 bit block multiplier available in Virtex-II and Virtex-II Pro. For multipliers larger than this, XST can generate larger multipliers using multiple 18x18 bit block multipliers.

## Registered Multiplier

For Virtex-II and Virtex-II Pro, in instances where a multiplier would have a registered output, XST will infer a unique registered multiplier. This registered multiplier will be 18x18 bits.

Under the following conditions, a registered multiplier will not be used, and a multiplier + register will be used instead.

- Output from the multiplier goes to any component other than the register
- The mult_style register is set to lut.
- The multiplier is asynchronous.
- The multiplier has control signals other than synchronous reset or clock enable.
- The multiplier does not fit in a single 18x18 bit block multiplier.
The following pins are optional for the registered multiplier.

## Log File

The XST log file reports the type and size of recognized multipliers during the macro recognition step:

Related source file is multipliers_1.vhd.

Found 8x4-bit multiplier for signal <res>.

==============================

## Unsigned 8x4-bit Multiplier

This section contains VHDL and Verilog descriptions of an unsigned 8x4-bit multiplier.

The following table shows pin descriptions for an unsigned 8x4-bit multiplier.

A[7:0], B[3:0] MULT Operands RES[7:0] MULT Result## VHDL

Following is the VHDL code for an unsigned 8x4-bit multiplier.

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity mult is port(A : in std_logic_vector(7 downto 0); B : in std_logic_vector(3 downto 0); RES : out std_logic_vector(11 downto 0)); end mult; architecture archi of mult is begin RES <= A * B; end archi;## Verilog

Following is the Verilog code for an unsigned 8x4-bit multiplier.

module compar(A, B, RES); input [7:0] A; input [3:0] B; output [11:0] RES; assign RES = A * B; endmodule## Dividers

Divisions are only supported, when the divisor is a constant and is a power of 2. In that case, the operator is implemented as a shifter; otherwise, an error message will be issued by XST.

## Log File

When you implement a division with a constant with the power of 2, XST does not issue any message during the macro recognition step. In case your division does not correspond to the case supported by XST, the following error message displays:

ERROR:Xst:719 - file1.vhd (Line 172).

## Division By Constant 2

This section contains VHDL and Verilog descriptions of a Division By Constant 2 divider.

The following table shows pin descriptions for a Division By Constant 2 divider.

DI[7:0] DIV Operands DO[7:0] DIV Result## VHDL

Following is the VHDL code for a Division By Constant 2 divider.

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity divider is port(DI : in unsigned(7 downto 0); DO : out unsigned(7 downto 0)); end divider; architecture archi of divider is begin DO <= DI / 2; end archi;## Verilog

Following is the Verilog code for a Division By Constant 2 divider.

module divider(DI, DO); input [7:0] DI; output [7:0] DO; assign DO = DI / 2; endmodule## Resource Sharing

The goal of resource sharing (also known as folding) is to minimize the number of operators and the subsequent logic in the synthesized design. This optimization is based on the principle that two similar arithmetic resources may be implemented as one single arithmetic operator if they are never used at the same time. XST performs both resource sharing and, if required, reduces of the number of multiplexers that are created in the process.

XST supports resource sharing for adders, subtractors, adders/subtractors and multipliers.

## Log File

The XST log file reports the type and size of recognized arithmetic blocks and multiplexers during the macro recognition step:

Related source file is resource_sharing_1.vhd.

Found 8-bit addsub for signal <res>.

Found 8 1-bit 2-to-1 multiplexers.

inferred 1 Adder/Subtracter(s).

==============================

## Related Constraint

The related constraint is resource_sharing.

## Example

For the following VHDL/Verilog example, XST will give the following solution:

The following table shows pin descriptions for the example.

A[7:0], B[7:0], B[7:0] DIV Operands OPER Operation Selector RES[7:0] Data Output## VHDL

Following is the VHDL example for resource sharing.

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all;port(A,B,C : in std_logic_vector(7 downto 0); OPER : in std_logic; RES : out std_logic_vector(7 downto 0)); end addsub; architecture archi of addsub is begin RES <= A + B when OPER='0' else A - C; end archi;## Verilog

Following is the Verilog code for resource sharing.

module addsub(A, B, C, OPER, RES); input OPER; input [7:0] A; input [7:0] B; input [7:0] C; output [7:0] RES; reg [7:0] RES; always @(A or B or C or OPER) begin if (OPER==1'b0) RES = A + B; else RES = A - C; end endmodule