AR# 8657: EXEMPLAR: How to implement a pipeline multiplier? (VHDL/Verilog)
EXEMPLAR: How to implement a pipeline multiplier? (VHDL/Verilog)
Keywords: multiply, pipelined, spectrum, leonardo
General Description: Pipelining a combinational logic involves putting levels of registers in the logic to introduce parallelism and, as a result, improve speed. Flip flops introduced by pipelining typically incur a minimum of additional area on FPGAs, by occupying the unused flip flops within logic cells that are already used for implementing combinational logic in the design.
LeonardoSpectrum requires certain constructs in the input RTL source code description to allow the pipelined multiplier feature to take effect. These constructs call for "m" levels of registers to be inferred at the output of the multiplier, where m is an integer greater than 1. Let n be the smallest integer that is greater than or equal to the base 2 logarithm of the width of the multiplier/multiplicand. LeonardoSpectrum automatically pipelines the multiplier by moving the first x levels of the inferred registers into the multiplier,
where x = m-1, for 2 <=m <=n or x = n-1, for m >n
The pipeline multiplier feature is turned on by default in LeonardoSpectrum 1999.1i and later.This feature can be disabled by setting the variable pipeline_mult to false.
set pipeline_mult false
For more information on this feature, please refer to the application note located in LeonardoSpectrum user manual : Help -> View User Manual -> User Manual -> ApplicationNotes -> Pipelined Multiplier.
The following is an RTL level description of a 16-bit, unsigned multiplier with the operand inputs registered. LeonardoSpectrum infers four levels of registers at the output of the multiplier and generates a 4-stage pipelined multiplier.
-- VHDL example library ieee ; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all;
entity pipelined_multiplier is
-- generic size is the width of multiplier/multiplicand; -- generic level is the intended number of stages of the -- pipelined multiplier; -- generic level is typically the smallest integer greater -- than or equal to base 2 logarithm of size, as returned by -- function log, which you define. generic (size : integer := 16; level : integer := log(size));
port ( a : in std_logic_vector (size-1 downto 0) ; b : in std_logic_vector (size-1 downto 0) ; clk : in std_logic; pdt : out std_logic_vector (2*size-1 downto 0)); end pipelined_multiplier ;
architecture exemplar of pipelined_multiplier is type levels_of_registers is array (level-1 downto 0) of unsigned (2*size-1 downto 0); signal a_int, b_int : unsigned (size-1 downto 0); signal pdt_int : levels_of_registers;
begin pdt <= std_logic_vector (pdt_int (level-1));
process(clk) begin if clk'event and clk = '1' then -- multiplier operand inputs are registered a_int <= unsigned (a); b_int <= unsigned (b); -- 'level' levels of registers to be inferred at the -- output of the multiplier pdt_int(0) <= a_int * b_int; for i in 1 to level-1 loop pdt_int (i) <= pdt_int (i-1); end loop; end if; end process; end exemplar ;
module pipelined_multiplier ( a, b, clk, pdt); /* * parameter 'size' is the width of multiplier/multiplicand;.Application Notes 10-5 * parameter 'level' is the intended number of stages of the * pipelined multiplier; * which is typically the smallest integer greater than or equal * to base 2 logarithm of 'size' */ parameter size = 16, level = 4; input [size-1 : 0] a; input [size-1 : 0] b; input clk; output [2*size-1 : 0] pdt; reg [size-1 : 0] a_int, b_int; reg [2*size-1 : 0] pdt_int [level-1 : 0]; integer i;
assign pdt = pdt_int [level-1];
always @ (posedge clk) begin // registering input of the multiplier a_int <= a; b_int <= b; // 'level' levels of registers to be inferred at the output // of the multiplier pdt_int <= a_int * b_int; for(i =1;i <level;i =i +1) pdt_int [i] <= pdt_int [i-1]; end // always @ (posedge clk) endmodule // pipelined_multiplier