120 lines
5.0 KiB
VHDL
120 lines
5.0 KiB
VHDL
----------------------------------------------------------------------------------------------------
|
|
-- Component : squareRoot_pipe
|
|
-- Author : pwkolas
|
|
----------------------------------------------------------------------------------------------------
|
|
-- File : squareRoot_pipe.vhd
|
|
-- Mod. Date : XX.XX.XXXX
|
|
-- Version : 1.00
|
|
----------------------------------------------------------------------------------------------------
|
|
-- Description : Square root calculator.
|
|
-- Based on
|
|
-- "A New Non-Restoring Square Root Algorithm and Its VLSI Implementations"
|
|
--
|
|
----------------------------------------------------------------------------------------------------
|
|
-- Modification History :
|
|
--
|
|
----------------------------------------------------------------------------------------------------
|
|
-- Comments :
|
|
--
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
library ieee;
|
|
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
entity squareRoot_pipe is
|
|
generic (
|
|
G_DATA_W : integer := 32
|
|
);
|
|
port (
|
|
clk : in std_logic;
|
|
rst : in std_logic;
|
|
iv_data : in std_logic_vector(G_DATA_W-1 downto 0);
|
|
ov_res : out std_logic_vector((G_DATA_W/2)-1 downto 0)
|
|
);
|
|
end entity squareRoot_pipe;
|
|
|
|
architecture squareRoot_pipe_rtl of squareRoot_pipe is
|
|
|
|
constant C_ALU_W : integer := ((G_DATA_W/2) + 2);
|
|
constant C_PIPE_L : integer := G_DATA_W/2;
|
|
constant C_OFFSET : integer := 3; -- width of start vectors going to ALU
|
|
|
|
type t_arr_pipe_x_data is array (C_PIPE_L-1 downto 0) of unsigned(G_DATA_W-1 downto 0);
|
|
signal a_data : t_arr_pipe_x_data; -- (D)
|
|
signal a_R : t_arr_pipe_x_data; -- (R)
|
|
|
|
type t_arr_pipe_x_alu is array (C_PIPE_L-1 downto 0) of unsigned(C_ALU_W-1 downto 0);
|
|
|
|
type t_arr_pipe_x_res is array (C_PIPE_L-1 downto 0) of unsigned(G_DATA_W/2-1 downto 0);
|
|
signal a_Q : t_arr_pipe_x_res; -- (ALU Q out)
|
|
|
|
signal nextOp : std_logic_vector(C_PIPE_L-1 downto 0);
|
|
|
|
begin
|
|
sqrt_p : process (clk, rst)
|
|
variable va_AluInR : t_arr_pipe_x_alu; -- (ALU R in)
|
|
variable va_AluInQ : t_arr_pipe_x_alu; -- (ALU Q in)
|
|
variable va_AluOut : t_arr_pipe_x_alu; -- (ALU Q out)
|
|
begin
|
|
if (rst = '1') then
|
|
a_data <= (others => (others => '0'));
|
|
a_R <= (others => (others => '0'));
|
|
a_Q <= (others => (others => '0'));
|
|
va_AluInR := (others => (others => '0'));
|
|
va_AluInQ := (others => (others => '0'));
|
|
va_AluOut := (others => (others => '0'));
|
|
nextOp <= (others => '0');
|
|
elsif rising_edge(clk) then
|
|
-- stage 0 start conditions, ALU inputs
|
|
va_AluInR(0) := (others => '0');
|
|
va_AluInR(0)(1 downto 0) := unsigned(iv_data(G_DATA_W-1 downto G_DATA_W-1-1));
|
|
va_AluInQ(0) := (others => '0');
|
|
va_AluInQ(0)(0) := '1';
|
|
|
|
-- stage 0 calculations
|
|
va_AluOut(0) := va_AluInR(0) - va_AluInQ(0);
|
|
|
|
-- stage 0 result registers, ALU output
|
|
a_data(0) <= shift_left(unsigned(iv_data), 2);
|
|
a_R(0) <= (others => '0');
|
|
a_R(0)(G_DATA_W-1 downto G_DATA_W-1-1) <= va_AluOut(0)(1 downto 0);
|
|
a_Q(0) <= (others => '0');
|
|
a_Q(0)(0) <= not va_AluOut(0)(2);
|
|
nextOp(0) <= not va_AluOut(0)(2);
|
|
|
|
-- next stages
|
|
for i in 1 to C_PIPE_L-1 loop
|
|
-- prepare inputs for next stage
|
|
va_AluInR(i) := (others => '0');
|
|
va_AluInR(i)(C_OFFSET+i-1 downto 2) := a_R(i-1)(G_DATA_W-(i-1)-1 downto G_DATA_W-(2*i));
|
|
va_AluInR(i)(2-1 downto 0) := a_data(i-1)(G_DATA_W-1 downto G_DATA_W-1-1);
|
|
va_AluInQ(i) := (others => '0');
|
|
va_AluInQ(i)(C_OFFSET+(i-1)-1 downto 2) := a_Q(i-1)(i-1 downto 0);
|
|
va_AluInQ(i)(1) := not a_Q(i-1)(0);
|
|
va_AluInQ(i)(0) := '1';
|
|
|
|
-- ALU ADD/SUB
|
|
if (nextOp(i-1) = '1') then
|
|
va_AluOut(i) := va_AluInR(i) - va_AluInQ(i);
|
|
else
|
|
va_AluOut(i) := va_AluInR(i) + va_AluInQ(i);
|
|
end if;
|
|
|
|
-- result registers
|
|
a_data(i) <= shift_left(unsigned(a_data(i-1)), 2);
|
|
a_R(i) <= (others => '0');
|
|
a_R(i)(G_DATA_W-i-1 downto G_DATA_W-2*(i+1)) <= va_AluOut(i)(i+1 downto 0);
|
|
a_Q(i) <= shift_left(unsigned(a_Q(i-1)), 1);
|
|
a_Q(i)(0) <= not va_AluOut(i)(i+2);
|
|
nextOp(i) <= not va_AluOut(i)(i+2);
|
|
|
|
end loop;
|
|
end if;
|
|
end process;
|
|
|
|
ov_res <= std_logic_vector(a_Q(C_PIPE_L-1));
|
|
|
|
end architecture squareRoot_pipe_rtl;
|