Bài viết trình bày việc thực hiện khối bộ nhân theo phương pháp Baugh-Wooley. Phương pháp Baugh-Wooley áp dụng cho cả phép nhân có dấu và không dấu. Toán tử có dấu được biểu diễn dưới dạng số bù hai để đảm bảo chắc chắn rằng dấu của các tích riêng phần luôn là dấu dương.
Mã nguồn VHDL mô tả bộ nhân theo phương pháp Baugh-Wooley:
----------------------------------------------------------------------------------
-- Company: Smart Electronics
-- Engineer: Nguyen Kiem Hung
--
-- Create Date: 15:10:31 03/09/2017
-- Design Name:
-- Module Name: mul_unit - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.all ;
use IEEE.std_logic_unsigned.all;
use work.RCA_define.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity mul_unit is
generic (
DATA_WIDTH : INTEGER :=16 );
Port ( A : in signed (DATA_WIDTH-1 downto 0);
B : in signed (DATA_WIDTH-1 downto 0);
P : out signed (DATA_WIDTH*2-1 downto 0));
end mul_unit;
architecture Behavioral of mul_unit is
type P_array is array (DATA_WIDTH- 1 downto 0) of signed (DATA_WIDTH-1 downto 0);
signal m_temp, p_temp, s_temp : P_array;
signal carry_temp: std_logic_vector (DATA_WIDTH-1 downto 0);
begin
gen_temp_m:
for i in 0 to DATA_WIDTH- 1 generate
begin
gen_each_m:
for j in 0 to DATA_WIDTH- 1 generate
begin
gen_m77:
if ((i = DATA_WIDTH- 1) and (j = DATA_WIDTH- 1)) generate
begin
m_temp(i)(j) <= (B(i) and A(j));
end generate;
gen_mx7_7x:
if (((i = DATA_WIDTH- 1) and (j /= DATA_WIDTH- 1)) or ((i /= DATA_WIDTH- 1) and (j = DATA_WIDTH- 1)))generate
begin
m_temp(i)(j) <= (not (B(i) and A(j)));
end generate;
gen_m_other:
if ((i /= DATA_WIDTH- 1) and (j /= DATA_WIDTH- 1)) generate
begin
m_temp(i)(j) <= (B(i) and A(j));
end generate;
end generate;
end generate;
carry_temp(0) <= '1';
p_temp(0) <= m_temp(0);
s_temp(0) <= (others=>'0');
gen_adder:
for i in 1 to DATA_WIDTH- 1 generate
begin
s_temp(i) <= carry_temp(i-1)&p_temp(i - 1)(DATA_WIDTH- 1 downto 1);
adder_unit: Look_Ahead_Adder generic MAP(
DATA_WIDTH => DATA_WIDTH
)
PORT MAP(
A => s_temp(i),
B => m_temp(i),
carry_in => '0',-- 0 <-> ADD; 1 <-> SUB
carry_out => carry_temp(i),
S => p_temp(i)
);
end generate;
P(DATA_WIDTH*2-1 downto DATA_WIDTH) <= (not (carry_temp(DATA_WIDTH- 1)))&p_temp(DATA_WIDTH- 1)(DATA_WIDTH- 1 downto 1);
gen_result:
for i in 0 to DATA_WIDTH- 1 generate
begin
P(i) <= p_temp(i)(0);
end generate;
end Behavioral;
