------------------------------------------------------------------------------- -- -- This is a Booth recoded 8x8 multiplier producing a 16-bit product. -- -- Shift and add are done in the same cycle -- -- Paul Chow -- Department of Electrical and Computer Engineering -- University of Toronto -- -- December 1997 -- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_signed.all; entity booth is port( iClk : in STD_LOGIC; iReset : in STD_LOGIC; iGo : in STD_LOGIC; oDone : out STD_LOGIC; iMer : in STD_LOGIC_VECTOR(7 downto 0); iMand : in STD_LOGIC_VECTOR(7 downto 0); oProduct : out STD_LOGIC_VECTOR(15 downto 0) ); end booth; architecture RTL of booth is type States is (WaitForGoState,InitState,AddShiftState,DoneState); signal PresentState, NextState : States; signal NumShifts : STD_LOGIC_VECTOR(1 downto 0); signal Product : STD_LOGIC_VECTOR(18 downto 0); signal Sum : signed (9 downto 0); begin -- RTL ------------------------------------------------------------------------------- -- This is the main FSM controller ------------------------------------------------------------------------------- Controller: process (iClk,iGo,PresentState,NumShifts) begin -- Controller case PresentState is when WaitForGoState => if (iGo = '1') then NextState <= InitState; else NextState <= WaitForGoState; end if; when InitState => NextState <= AddShiftState; when AddShiftState => if (NumShifts = "00") then NextState <= DoneState; else NextState <= AddShiftState; end if; when DoneState => NextState <= DoneState; end case; -- PresentState end process Controller; StateRegs: process (iClk,iReset) begin -- StateRegs if (iReset = '1') then PresentState <= WaitForGoState; elsif (iClk'event and iClk ='1') then PresentState <= NextState; end if; end process StateRegs; ------------------------------------------------------------------------------- -- This does the addition of the appropriate version of the multiplicand ------------------------------------------------------------------------------- Adder: process (Product,iMand) variable Mand1,Mand2 : signed (9 downto 0); begin -- Adder Mand1 := conv_signed(signed(iMand),10); Mand2 := shl(Mand1,"1"); case Product(2 downto 0) is when "000" => Sum <= signed(Product(18 downto 9)); when "001" => Sum <= signed(Product(18 downto 9)) + Mand1; when "010" => Sum <= signed(Product(18 downto 9)) + Mand1; when "011" => Sum <= signed(Product(18 downto 9)) + Mand2; when "100" => Sum <= signed(Product(18 downto 9)) - Mand2; when "101" => Sum <= signed(Product(18 downto 9)) - Mand1; when "110" => Sum <= signed(Product(18 downto 9)) - Mand1; when others => Sum <= signed(Product(18 downto 9)); end case; -- Product(2 downto 0) end process Adder; ------------------------------------------------------------------------------- -- This is the Product register and counter ------------------------------------------------------------------------------- ProdReg: process (iClk,iReset) variable ShiftedSum : signed(11 downto 0); begin -- ProdReg if (iClk'event and iClk = '1') then case PresentState is when WaitForGoState => when InitState => Product(18 downto 9) <= "0000000000"; Product(8 downto 1) <= iMer; Product(0) <= '0'; NumShifts <= "11"; when AddShiftState => ----------------------------------------------------------- -- This takes the Sum, sign extends it to 12 bits and -- puts that into the top part of the Product register, -- effectively shifting it at the same time. The bottom -- part of the register is loaded with a shifted value of -- the previous contents in that part. -- The counter is also updated here. ----------------------------------------------------------- ShiftedSum := conv_signed(signed(Sum),12); Product(18 downto 7) <= STD_LOGIC_VECTOR(ShiftedSum); Product(6 downto 0) <= Product(8 downto 2); NumShifts <= NumShifts - 1; when DoneState => end case; -- PresentState end if; end process ProdReg; ------------------------------------------------------------------------------- -- The output product and done signal. ------------------------------------------------------------------------------- oProduct <= Product(16 downto 1); oDone <= '1' when PresentState = DoneState else '0'; end RTL; -- of booth