## Arithmetic Operations

XST supports the following arithmetic operations:

• Carry In
• Carry Out
• Carry In/Out
• Subtractors
• Comparators (=, /=,<, <=, >, >=)
• Multipliers
• Dividers

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.

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:
 .. Synthesizing Unit . Related source file is arithmetic_operations_1.vhd. Found 8-bit adder for signal . Summary: inferred 1 Adder/Subtracter(s). Unit synthesized. ============================= HDL Synthesis Report Macro Statistics # Adders/Subtractors : 1 8-bit adder : 1 ==============================

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.
IO pins
Description
A[7:0], B[7:0]
SUM[7:0]

##### 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;

port(A,B : in std_logic_vector(7 downto 0);
SUM : out std_logic_vector(7 downto 0));
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.
IO pins
Description
A[7:0], B[7:0]
CI
Carry In
SUM[7:0]

##### 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;

port(A,B : in std_logic_vector(7 downto 0);
CI  : in std_logic;
SUM : out std_logic_vector(7 downto 0));
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

Res <= ("0" & A) + ("0" & B);

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
IO pins
Description
A[7:0], B[7:0]
SUM[7:0]
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;

port(A,B : in std_logic_vector(7 downto 0);
SUM : out std_logic_vector(7 downto 0);
CO  : out std_logic);
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 ;
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.
IO pins
Description
A[7:0], B[7:0]
CI
Carry In
SUM[7:0]
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;

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);
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 ;
endmodule
```

The following table shows pin descriptions for a simple signed 8-bit adder.
IO pins
Description
A[7:0], B[7:0]
SUM[7:0]

##### 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;

port(A,B : in std_logic_vector(7 downto 0);
SUM : out std_logic_vector(7 downto 0));
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.
IO pins
Description
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
```

The following table shows pin descriptions for an unsigned 8-bit adder/subtractor.
IO pins
Description
A[7:0], B[7:0]
OPER
SUM[7:0]

##### 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;

port(A,B : in std_logic_vector(7 downto 0);
OPER: in std_logic;
RES : out std_logic_vector(7 downto 0));
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:
 ... Synthesizing Unit . ��Related source file is comparators_1.vhd. ��Found 8-bit comparator greatequal for signal <\$n0000> created at line 10. Summary: inferred 1 Comparator(s). Unit synthesized. ============================= HDL Synthesis Report Macro Statistics # Comparators : 1 8-bit comparator greatequal : 1 ============================== ...

#### Unsigned 8-bit Greater or Equal Comparator

The following table shows pin descriptions for a comparator.
IO pins
Description
A[7:0], B[7:0]
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.

• clock enable port
• synchronous and asynchronous reset, reset, and load ports

#### Log File

The XST log file reports the type and size of recognized multipliers during the macro recognition step:
 ... Synthesizing Unit . Related source file is multipliers_1.vhd. Found 8x4-bit multiplier for signal . Summary: inferred 1 Multiplier(s). Unit synthesized. ============================== HDL Synthesis Report Macro Statistics # Multipliers : 1 8x4-bit multiplier : 1 ============================== ...

#### 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.
IO pins
Description
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). Operator is not supported yet : 'DIVIDE' ...

#### 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.
IO pins
Description
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.

#### Log File

The XST log file reports the type and size of recognized arithmetic blocks and multiplexers during the macro recognition step:
 ... Synthesizing Unit . Related source file is resource_sharing_1.vhd. Found 8-bit addsub for signal . Found 8 1-bit 2-to-1 multiplexers. Summary: inferred 1 Adder/Subtracter(s). inferred 8 Multiplexer(s). Unit synthesized. ============================== HDL Synthesis Report Macro Statistics # Multiplexers : 1 2-to-1 multiplexer : 1 # Adders/Subtractors : 1 8-bit addsub : 1 ============================== ...

#### 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.
IO pins
Description
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));
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
```