--! Unsigned division circuit, based on slow division algorithm (Restoring division)
|
--! Unsigned division circuit, based on slow division algorithm (Restoring division)
|
--! http://en.wikipedia.org/wiki/Division_%28digital%29
|
--! http://en.wikipedia.org/wiki/Division_%28digital%29
|
library IEEE;
|
library IEEE;
|
use IEEE.STD_LOGIC_1164.ALL;
|
use IEEE.STD_LOGIC_1164.ALL;
|
use IEEE.std_logic_arith.all;
|
use IEEE.std_logic_arith.all;
|
|
|
--! Use CPU Definitions package
|
--! Use CPU Definitions package
|
use work.pkgDefinitions.all;
|
use work.pkgDefinitions.all;
|
|
|
entity divisor is
|
entity divisor is
|
Port ( rst : in STD_LOGIC;
|
Port ( rst : in STD_LOGIC;
|
clk : in STD_LOGIC;
|
clk : in STD_LOGIC;
|
quotient : out STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
quotient : out STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
reminder : out STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
reminder : out STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
numerator : in STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
numerator : in STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
divident : in STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
divident : in STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
done : out STD_LOGIC);
|
done : out STD_LOGIC);
|
end divisor;
|
end divisor;
|
|
|
architecture Behavioral of divisor is
|
architecture Behavioral of divisor is
|
|
|
begin
|
begin
|
|
|
-- Division algorithm Q=N/D
|
-- Division algorithm Q=N/D
|
process (rst, clk, numerator, divident)
|
process (rst, clk, numerator, divident)
|
variable Q : unsigned(quotient'length-1 downto 0);
|
variable Q : unsigned(quotient'length-1 downto 0);
|
variable R : unsigned(reminder'length-1 downto 0);
|
variable R : unsigned(reminder'length-1 downto 0);
|
variable D : unsigned(reminder'length-1 downto 0);
|
variable D : unsigned(reminder'length-1 downto 0);
|
variable N : unsigned(reminder'length-1 downto 0);
|
variable N : unsigned(reminder'length-1 downto 0);
|
variable iteractions : integer;
|
variable iteractions : integer;
|
begin
|
begin
|
if (rst = '1') then
|
if (rst = '1') then
|
quotient <= (others => '0');
|
quotient <= (others => '0');
|
reminder <= (others => '0');
|
reminder <= (others => '0');
|
done <= '0';
|
done <= '0';
|
|
|
-- Initialize variables
|
-- Initialize variables
|
iteractions := quotient'length;
|
iteractions := quotient'length;
|
D := unsigned(divident);
|
D := unsigned(divident);
|
N := unsigned(numerator);
|
N := unsigned(numerator);
|
-- initialize quotient and remainder to zero
|
-- initialize quotient and remainder to zero
|
Q := (others => '0');
|
Q := (others => '0');
|
R := (others => '0');
|
R := (others => '0');
|
elsif rising_edge(clk) then
|
elsif rising_edge(clk) then
|
if iteractions > 0 then
|
if iteractions > 0 then
|
iteractions := iteractions - 1;
|
iteractions := iteractions - 1;
|
-- left-shift R by 1 bit
|
-- left-shift R by 1 bit
|
R := (R((R'HIGH - 1) downto 0) & '0');
|
R := (R((R'HIGH - 1) downto 0) & '0');
|
|
|
--set the least-significant bit of R equal to bit i of the numerator(dividend)
|
--set the least-significant bit of R equal to bit i of the numerator(dividend)
|
R(0) := N(iteractions);
|
R(0) := N(iteractions);
|
|
|
if (R >= D) then
|
if (R >= D) then
|
R := R - D;
|
R := R - D;
|
Q(iteractions) := '1';
|
Q(iteractions) := '1';
|
end if;
|
end if;
|
else
|
else
|
done <= '1';
|
done <= '1';
|
quotient <= CONV_STD_LOGIC_VECTOR(Q,32);
|
quotient <= CONV_STD_LOGIC_VECTOR(Q,32);
|
reminder <= CONV_STD_LOGIC_VECTOR(R,32);
|
reminder <= CONV_STD_LOGIC_VECTOR(R,32);
|
|
|
|
-- Used to avoid transparent latch (Good practise)
|
|
D := unsigned(divident);
|
|
N := unsigned(numerator);
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
end Behavioral;
|
end Behavioral;
|
|
|
|
|