-- bmul_ser.vhdl multiplier implemented as serial adds (one 32 bit adder) -- needs a 32 bit adder called add32, and full adder stage called fadd -- Booth multiplier for two's complement -- This example uses a signal as a register, uses 'when' as a mux -- modify to suit your needs. -- Booth multiply control table -- B multiplicand b=md -b=nmd +2b=md2 -2b=nmd2 -- i+1 i i-1 mulb -- 0 0 0 0 -- 0 0 1 +b -- 0 1 0 +b -- 0 1 1 +2b -- 1 0 0 -2b cin='1' -- 1 0 1 -b cin='1' -- 1 1 0 -b cin='1' -- 1 1 1 0 entity bmul_ser is -- test bench end bmul_ser; library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_textio.all; use STD.textio.all; architecture schematic of bmul_ser is subtype word is std_logic_vector(31 downto 0); signal md : word := x"A0010007"; -- multiplier or divisor signal hi : word := x"00000000"; -- top register (final=00000002) signal lo : word := x"00000011"; -- bottom register (final=20110077) signal cout : std_logic; -- adder carry out signal muls : word := x"00000000"; -- adder sum signal mulb : word := x"00000000"; -- multiplexor output signal clk : std_logic := '0'; -- system clock signal mulclk : std_logic := '0'; -- multiplier clock signal mulenb : std_logic := '1'; -- enable multiplication signal cntr : std_logic_vector(5 downto 0) := "000000"; -- counter signal B : std_logic_vector(2 downto 0) := "000"; -- Booth control signal lobit : std_logic := '0'; -- low Booth bit signal cout2 : std_logic; -- extra bit signal sum2 : std_logic; -- extra bit signal top2 : std_logic; -- extra bit signal nmd : word; -- negative of md signal md2 : word; -- two times md signal nmd2 : word; -- two times negative md signal cin : std_logic; -- for +/- b begin -- schematic of bmul_ser clk <= not clk after 5 ns; -- 10 ns period cntr <= unsigned(cntr)+unsigned'("000001") when clk'event and clk='1'; -- cntr statement is equivalent to six bit adder and clocked register nmd <= not md; md2 <= md(30 downto 0) & '0'; nmd2 <= not md2; mulenb <= '0' when (cntr="010001"); -- enable/disable multiply mulclk <= clk and mulenb after 50 ps; -- the multipliers "private" clock -- multiplier structure, not a component! B <= lo(1) & lo(0) & lobit; mulb <= md when B="001" or B="010" -- 5 input mux else md2 when B="011" else nmd2 when B="100" else nmd when B="101" or B="110" else x"00000000" after 50 ps; -- "000" and "111" case top2 <= md(31) when B="001" or B="010" or B="011" else not md(31) when B="100" or B="101" or B="110" else '0'; cin <= '1' when B="100" or B="101" or B="110" else '0'; adder:entity WORK.add32 port map(hi, mulb, cin, muls, cout); -- 32 bit adder xtra:entity WORK.fadd port map(hi(31),top2 ,cout, sum2, cout2); --1 bit adder hi <= sum2 & sum2 & muls(31 downto 2) when mulclk'event and mulclk='1'; lo <= muls(1 downto 0) & lo(31 downto 2) when mulclk'event and mulclk='1'; lobit <= lo(1) when mulclk'event and mulclk='1'; printout: postponed process(clk) -- just to see values variable my_line : LINE; -- not part of working circuit begin if clk='0' then -- quiet time, falling clock if cntr="000000" then write(my_line, string'("md=")); hwrite(my_line, md); writeline(output, my_line); end if; write(my_line, string'("at count ")); write(my_line, cntr); write(my_line, string'(" mulb=")); hwrite(my_line, mulb); write(my_line, string'(" muls=")); hwrite(my_line, muls); write(my_line, string'(" hi=")); hwrite(my_line, hi); write(my_line, string'(" lo=")); hwrite(my_line, lo); write(my_line, string'(" B=")); write(my_line, lo(1)); write(my_line, lo(0)); write(my_line, lobit); writeline(output, my_line); end if; end process printout; end schematic; -- of bmul_ser