DLX-Microprocessor / components / booth_mul.vhd
booth_mul.vhd
Raw
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use WORK.constants.all;

entity BOOTHMUL is
    Generic ( N : integer := numBit );
    Port (
            A: in std_logic_vector(N-1 downto 0);
            B: in std_logic_vector(N-1 downto 0);
            P: out std_logic_vector(2*N-1 downto 0)
        );
end BOOTHMUL;

-- the booth multiplier works on at least 3 bits

architecture mul_struct of BOOTHMUL is

-- Signals
signal zeros : std_logic_vector( N -1 downto 0 );               -- Used to extend A 
signal ext_A : std_logic_vector( 2*N -1 downto 0 );              -- A expanded to 2N bits

signal sel_sig : std_logic_vector( ((N/2)*3)-1 downto 0 );    -- Nbits which is B operands +1 for the first stage
signal B0 : std_logic_vector( 2 downto 0 );


-- n sum stages is N/2-1
signal shiftout_sig : std_logic_vector((2*N * ((N/2))) - 1 downto 0); -- N bits for each stage for the mux output

signal sum_sig : std_logic_vector((2*N * (N/2)) - 1 downto 0);    -- 32bit x ((N/2 - 1)adders - 1)
signal Vp_sig : std_logic_vector((2*N * ((N/2)-1)) - 1 downto 0);   -- 32bit x (N/2)muxes one for each stage

-- Components
component encoder is
    Port (
            y: in std_logic_vector(2 downto 0);
            sel: out std_logic_vector(2 downto 0)
        );
end component;

component mux5to1 is
    Generic ( N: integer := N );  
    Port (
            sel: in std_logic_vector(2 downto 0);
            A  : in std_logic_vector(N -1 downto 0);
            Vp : out std_logic_vector(N -1 downto 0)
        );
end component;

component RCA is
    generic (N : integer := 2*N);
    port (
            A  : in std_logic_vector(N - 1 downto 0);
            B  : in std_logic_vector(N - 1 downto 0);
            Ci : in std_logic;
            S  : out std_logic_vector(N - 1 downto 0);
            Co : out std_logic
         );
end component;
  
component left_shifter is
    Generic (
                N: integer := 2*N;
                pos: integer := 1
            );
    Port (
            A  : in std_logic_vector(N-1 downto 0);
            A_shifted : out std_logic_vector(N-1 downto 0)
         );
end component;

component P4_ADDER is 
	generic (
			N:	integer := 2*N;
			NBIT_BLOCK:	integer := 4	
		);		

	port (	A:	in	std_logic_vector(N - 1 downto 0);	
			B:	in	std_logic_vector(N - 1 downto 0);	
			Ci:	in	std_logic;				
			S:	out	std_logic_vector(N - 1 downto 0);	
			Co:	out	std_logic);				
    end component;


begin
-- Extend A
zeros <= (others => '0');
ext_A <= zeros & A;

-- Prepare the first encoder input
B0 <= B(1 downto 0)&'0';

-- First stage is only a MUX with the select bits
E0 : encoder port map (
                        y => B0, 
                        sel => sel_sig(2 downto 0)
                      );

MUX0 : mux5to1 generic map (
                                N => 2*N
                            )
                port map (
                            sel => sel_sig(2 downto 0), 
                            A   => ext_A,                -- A
                            Vp  => sum_sig(2*N-1 downto 0)
                        );
-- need to shift A by 2 positions to get 4A
SH0 : left_shifter generic map (
                            N => 2*N,
                            pos => 2
                        )  
                        port map (
                            A  => ext_A, 
                            A_shifted => shiftout_sig(2*N-1 downto 0)
                        );
-- A is now 4Anull

-- now we generate for the number of true stages 

booth_stages : for i in 1 to ((N/2) - 1) generate -- N=8
    -- generate the stage encoder
    EXi : encoder port map (
                            y => B((i*2)+1 downto (i*2)-1), 
                            sel => sel_sig((i*3)+2 downto (i*3)) 
                          );

    -- -- generate the stage multiplexer
    MUXi : mux5to1 generic map (
                                N => 2*N
                                ) 
                    port map (
                                sel => sel_sig((i*3)+2 downto (i*3)), 
                                A   => shiftout_sig(2*N*(i)-1 downto 2*N*(i-1)),    -- 4*iA shift selection generated in the previous stage 
                                Vp  => Vp_sig(2*N*(i)-1 downto 2*N*(i-1))           -- Update the current    
                    );

    -- -- generate the stage shifter for the next A value 
    SHi : left_shifter generic map (
                                N => 2*N,
                                pos => 2
                            )  
                            port map (
                                A  => shiftout_sig(2*N*(i)-1 downto 2*N*(i-1)),  -- Take the previous A value 
                                A_shifted => shiftout_sig(2*N*(i+1)-1 downto 2*N*(i))   -- Shift of 2 further bits 4*(i+1)A
                            );

    -- generate the sium generator
    -- SUMi: rca generic map (N => 2*N) 
    --     port map (
    --                 A   => sum_sig(2*N*(i)-1 downto 2*N*(i-1)),    -- Add the previous sum result to the 
    --                 B   => Vp_sig(2*N*(i)-1 downto 2*N*(i-1)),       -- current mux output
    --                 Ci  => '0', 
    --                 S   => sum_sig(2*N*(i+1)-1 downto 2*N*(i)),    -- Assign it to the current stage sum output
    --                 Co  => open                            
    --             );
    Pi: P4_ADDER  
        generic map(
                N => 2*N,
                NBIT_BLOCK => 4	
            )		    
        port map(	
                A   => sum_sig(2*N*(i)-1 downto 2*N*(i-1)),    -- Add the previous sum result to the 
                B   => Vp_sig(2*N*(i)-1 downto 2*N*(i-1)),       -- current mux output
                Ci  => '0', 
                S   => sum_sig(2*N*(i+1)-1 downto 2*N*(i)),    -- Assign it to the current stage sum output
                Co  => open
        );				

    -- sum_sig(2*N*(i+1)-1 downto 2*N*(i)) <= std_logic_vector(unsigned(sum_sig(2*N*(i)-1 downto 2*N*(i-1))) + unsigned(Vp_sig(2*N*(i)-1 downto 2*N*(i-1))));
end generate;

-- The last sum is the last part of the sum signal
P <= sum_sig((2*N*(N/2))-1 downto (2*N*((N/2)-1)));

end architecture;