Return to previous page Advance to next page

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:

..

Synthesizing Unit <adder>.

Related source file is arithmetic_operations_1.vhd.

Found 8-bit adder for signal <sum>.

Summary:

inferred 1 Adder/Subtracter(s).

Unit <adder> synthesized.

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

HDL Synthesis Report

Macro Statistics

# Adders/Subtractors : 1

8-bit adder : 1

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

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

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.

The following table shows pin descriptions for an unsigned 8-bit adder with carry
IO pins
Description
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:

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

Unsigned 8-bit Adder/Subtractor

The following table shows pin descriptions for an unsigned 8-bit adder/subtractor.
IO pins
Description
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:

...

Synthesizing Unit <compar>.

  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 <compar> 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]
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.

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:

...

Synthesizing Unit <mult>.

Related source file is multipliers_1.vhd.

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

Summary:

inferred 1 Multiplier(s).

Unit <mult> 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.

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:

...

Synthesizing Unit <addsub>.

Related source file is resource_sharing_1.vhd.

Found 8-bit addsub for signal <res>.

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

Summary:

inferred 1 Adder/Subtracter(s).

inferred 8 Multiplexer(s).

Unit <addsub> 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; 
 
entity addsub is
  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 

Return to previous page Advance to next page