Utilizing the Virtex II Multimedia Hardware Multipliers

By: Ramkrishna Swamy, Maziyar Khorasani, Yongjie Liu, Rejean Lau

 

The Xilinx Virtex II Multimedia FPGAs contain hardware multipliers. This allows multiplication to be done inside the FPGA without the use of large numbers of LUTs and also at a low power cost. The multipliers have input data bus widths of 18 bits and an output data bus width of 36 bits.

 

To instantiate the 18x18 signed multipliers, you must first sign extend the inputs if they are less than 18 since the hardware requires the sign bit be the MSB.  As an example,

 

1111 (unsigned value of 15) = 000000000000001111 (signed value of 15 extended to 18 bits)

1111 (signed value of –1) = 111111111111111111 (signed value of –1 extended to 18 bits)

 

NOTE: The signed values are in 2’s complement.

 

It is possible to instantiate two versions of this hardware multiplier:

1)      Pipelined (higher performance, extra latency) – not described in this document.

2)      Un-pipelined (completely combinational)

 

It is possible to infer hardware multipliers using ISE 6.2i, in the following manner:

 

A <= B * C; where      A : std_logic_vector(35 downto 0)

B : std_logic_vector (17 downto 0)

C : std_logic_vector (17 downto 0)

 

It is obvious that the multiplier will run at higher speeds when multiplying fewer bits (input busses).  Therefore, if the user requires a small multiplier in the design, it will be more beneficial for the user to infer a smaller multiplier using CLBs and not use the hardware multipliers.

 

The multipliers will run faster if fewer bits are used and the MSBs are tied to ‘0’. 200MHz+ performance is possible by following the Xilinx application note Xapp636 that describes how it is possible to improve the operation of the multipliers (refer to [2]).

 

Core Generator IP Modules

 

It is useful to use these modules as they provide additional control signals and offer greater flexibility.  The following will describe how to create an 18x18 signed and un-pipelined multiplier via the Core Generator v6.0. However, the same template and procedure can be used to implement pipelined multipliers and even other Core Generator modules.

 

The user require two main blocks:

1)      Core Generator module (*.xco), that (2) instantiates as a black box.

2)      Top-level entity that can be used by any design.

 

First, we must generate the *.xco file:

a)      “Project” and go to “New source…”

b)      Select “IP (CoreGen & Architecture Wizard)” and enter in the file name.

 

c)      In the CoreGen window, ensure the information is selected as shown below.  Then click “Next”.

 

 

d)      If you are building an 18x18 combinational multiplier, select options as shown below.  Otherwise, you may configure it as you wish using the “Data Sheet…”.  Once it is configured, click “Next…”.

 

e)      Once again, this is not pipelined, hence, you may select the “Non Registered” radio button.  You may also setup handshaking signals as required.

 

 

f)        If you require zero latency in the multiplier, select “Minimum Pipelining”.  Upon configuring as shown below, click “Generate” to create the <coregen_toplevel>.xco file.

 

Second, you must instantiate the CoreGen module in a top-level file as a black box such that the synthesizer does not optimize the block away.  If you are using earlier versions of ISE and you encounter parse errors within the generated module, you must refer to [3] to solve problems dealing with CoreGen instantiations.

The following describes a template by which you may use instantiate a black box entity:

 

library IEEE;

use IEEE.std_logic_1164.all;

 

ENTITY <entity_name> IS

PORT (

                a, b      : IN STD_LOGIC_VECTOR(17 downto 0);

                q         : OUT STD_LOGIC_VECTOR(35 downto 0)

                );

END <entity_name>;

 

ARCHITECTURE rtl OF <entity_name> IS

 

ATTRIBUTE box_type: STRING;

 

COMPONENT <coregen_toplevel>

PORT (

                a: IN std_logic_VECTOR(17 downto 0);

                b: IN std_logic_VECTOR(17 downto 0);

                o: OUT std_logic_VECTOR(35 downto 0)

                );

END COMPONENT;

 

ATTRIBUTE box_type OF <coregen_toplevel>: COMPONENT IS "black_box";

 

BEGIN

multiply_it: <coregen_toplevel>

                PORT MAP (

                                a => a,

                                b => b,

                                o => q

                                );

END rtl;

 

In the above, the <coregen_toplevel> is the same component declaration as found in the “Functional Model” of the newly added CoreGen module.  Therefore, the entity <entity_name> is the component that any design may instantiate to make use of this CoreGen module.

Additional Links

 

[1] For reference on VHDL/Verilog syntax – refer to http://toolbox.xilinx.com/docsan/xilinx6/books/data/docs/v4ldl/v4ldl0057_50.html

[2] For Optimal use of multipliers – refer to http://www.xilinx.com/ipcenter/catalog/search/reference/reference_xapp636_optimal_pipelining_vii-multipliers.htm

[3] To resolve the "HDLParsers:164" Error – refer to http://support.xilinx.com/xlnx/xil_ans_display.jsp?iLanguageID=1&iCountryID=1&getPagePath=19221