OpenCores
URL https://opencores.org/ocsvn/raytrac/raytrac/trunk

Subversion Repositories raytrac

[/] [raytrac/] [trunk/] [sqrtdiv/] [sqrtdiv.vhd] - Rev 158

Go to most recent revision | Compare with Previous | Blame | View Log

--! @file sqrtdiv.vhd
--! @brief Unidad aritm'etica para calcular la potencia de un n'umero entero elevado a la -1 (INVERSION) o a la 0.5 (SQUARE_ROOT).
--! @author Juli´n Andrés Guarín Reyes.
-- RAYTRAC
-- Author Julian Andres Guarin
-- sqrtdiv.vhd
-- This file is part of raytrac.
-- 
--     raytrac is free software: you can redistribute it and/or modify
--     it under the terms of the GNU General Public License as published by
--     the Free Software Foundation, either version 3 of the License, or
--     (at your option) any later version.
-- 
--     raytrac is distributed in the hope that it will be useful,
--     but WITHOUT ANY WARRANTY; without even the implied warranty of
--     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--     GNU General Public License for more details.
-- 
--     You should have received a copy of the GNU General Public License
--     along with raytrac.  If not, see <http://www.gnu.org/licenses/>.
 
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.math_real.all;
 
use work.arithpack.all;
 
 
entity sqrtdiv is
	generic (
		reginput: string	:= "YES";
		c3width	: integer	:= 18;
		functype: string	:= "INVERSION"; 
		iwidth	: integer	:= 32;
		awidth	: integer	:= 9
	);
	port (
		clk,rst	: in std_logic;
		value	: in std_logic_vector (iwidth-1 downto 0);
		zero	: out std_logic;
 
		sqr		: out std_logic_vector (15 downto 0);
		inv		: out std_logic_vector (16 downto 0)
	);
end sqrtdiv;
 
architecture sqrtdiv_arch of sqrtdiv is
 
	--! expomantis::Primera etapa: Calculo parcial de la mantissa y el exponente.
	signal expomantisvalue	: std_logic_vector (iwidth-1 downto 0);
 
	signal expomantisexp	: std_logic_vector (2*integer(ceil(log(real(iwidth),2.0)))-1 downto 0);
	signal expomantisadd	: std_logic_vector (2*awidth-1 downto 0);
	signal expomantiszero	: std_logic;
 
	--! funky::Segunda etapa: Calculo del valor de la funcion evaluada en f.
	signal funkyadd			: std_logic_vector (2*awidth-1 downto 0);
	signal funkyexp			: std_logic_vector (2*integer(ceil(log(real(iwidth),2.0)))-1 downto 0);
	signal funkyzero		: std_logic;
 
	signal funkyq			: std_logic_vector (2*c3width-1  downto 0);
	signal funkyselector	: std_logic;
 
	--! cumpa::Tercera etapa: Selecci'on de valores de acuerdo al exp escogido.
	signal cumpaexp			: std_logic_vector (2*integer(ceil(log(real(iwidth),2.0)))-1 downto 0);
	signal cumpaq			: std_logic_vector (2*c3width-1 downto 0);
	signal cumpaselector	: std_logic;
	signal cumpazero		: std_logic;
 
	signal cumpaN			: std_logic_vector (integer(ceil(log(real(iwidth),2.0)))-1 downto 0);
	signal cumpaF			: std_logic_vector (c3width-1 downto 0);
 
	--! chief::Cuarta etapa: Corrimiento a la izquierda o derecha, para el caso de la ra'iz cuadrada o la inversi'on respectivamente. 
 
	signal chiefN			: std_logic_vector (integer(ceil(log(real(iwidth),2.0)))-1 downto 0);
	signal chiefF			: std_logic_vector (c3width-1 downto 0);
	signal chiefQ			: std_logic_vector (c3width-1 downto 0);
 
	--! inverseDistance::Quinta etapa
 
	signal iDistN			: std_logic_vector (integer(ceil(log(real(iwidth),2.0)))-1 downto 0);
	signal iDistF			: std_logic_vector (c3width-1 downto 0);
	--! Constantes para manejar el tama&ntilde;o de los vectores
	constant exp1H : integer := 2*integer(ceil(log(real(iwidth),2.0)))-1;
	constant exp1L : integer := integer(ceil(log(real(iwidth),2.0)));
	constant exp0H : integer := exp1L-1;
	constant exp0L : integer := 0;
	constant add1H : integer := 2*awidth-1;
	constant add1L : integer := awidth;
	constant add0H : integer := awidth-1;
	constant add0L : integer := 0;
 
 
	constant c3qHH : integer := 2*c3width-1;
	constant c3qHL : integer := c3width;
	constant c3qLH : integer := c3width-1;
	constant c3qLL : integer := 0;
 
begin
 
	--! expomantis.
	expomantisreg:
	if reginput="YES" generate
		expomantisProc:
		process (clk,rst)
		begin
			if rst=rstMasterValue then
				expomantisvalue <= (others =>'0');
			elsif clk'event and clk='1' then
				expomantisvalue <= value;
			end if;
		end process expomantisProc;
	end generate expomantisreg;
 
	expomantisnoreg:
	if reginput ="NO" generate
		expomantisvalue<=value;
	end generate expomantisnoreg;
 
	expomantisshifter2x:shifter2xstage
	generic map(awidth,iwidth)
	port map(expomantisvalue,expomantisexp,expomantisadd,expomantiszero);
 
	--! funky.
	funkyProc:
	process (clk,rst,expomantisexp, expomantiszero)
	begin
		if rst=rstMasterValue then
			funkyexp <= (others => '0');
			funkyzero <= '0';
			funkyadd <= (others => '0');
 
		elsif clk'event and clk='1' then
 
			funkyexp(exp1H downto 0) <= expomantisexp(exp1H downto 0);
			funkyzero <= expomantiszero;
			funkyadd <= expomantisadd;
 
		end if;
	end process funkyProc;
 
	funkyget:
	process (funkyexp)
	begin
		if (funkyexp(exp0H downto 0)>funkyexp(exp1H downto exp1L)) then
			funkyselector<='0';
		else
			funkyselector<='1';
		end if;
	end process funkyget;
 
 
 
	sqrt: funcinvr
	generic map (memoryPath&"memsqrt.mif")
	port map(
		funkyadd(awidth-1 downto 0),
		clk,
		funkyq(c3qLH downto c3qLL));
 
	sqrt2x: funcinvr
	generic map (memoryPath&"memsqrt2f.mif")
	port map(
		funkyadd(2*awidth-1 downto awidth),
		clk,
		funkyq(c3qHH downto c3qHL));
 
 
	--! cumpa.
	cumpaProc:
	process (clk,rst)
	begin
		if rst=rstMasterValue then
			cumpaselector <= '0';
			cumpazero <= '0';
			cumpaexp <= (others => '0');
			cumpaq <= (others => '0');
		elsif clk'event and clk='1' then
			cumpaselector <= funkyselector;
			cumpazero <= funkyzero;
			cumpaexp <= funkyexp;
			cumpaq <= funkyq;
		end if;
	end process cumpaProc;
	cumpaMux:
	process (cumpaq,cumpaexp,cumpaselector)
	begin
		if cumpaselector='0' then
			cumpaN<=cumpaexp(exp0H downto exp0L);
			cumpaF<=cumpaq(c3qLH downto c3qLL);
		else
			cumpaN<=cumpaexp(exp1H downto exp1L);					 		
			cumpaF<=cumpaq(c3qHH downto c3qHL);
		end if;
	end process cumpaMux;
 
	--! Branching.
	-- exp <= chiefN;
	-- fadd <= chiefF(c3width-2 downto c3width-1-awidth);
	chiefProc:
	process (clk,rst)
	begin 
		if rst=rstMasterValue then
			chiefF <= (others => '0');
			chiefN <= (others => '0');
		elsif clk'event and clk='1' then
			chiefF <= cumpaF;
			chiefN <= cumpaN;
			zero <= cumpazero;
		end if;
	end process chiefProc;
	chiefShifter: RLshifter
	generic map("SQUARE_ROOT",c3width,iwidth,16)
	port map(
		chiefN,
		chiefF,
		sqr);
	branching_invfunc:
	if functype="INVERSION" generate
		sqrt: funcinvr
		generic map (memoryPath&"meminvr.mif")
		port map(
			chiefF(c3width-2 downto c3width-1-awidth),
			clk,
			chiefQ(c3width-1 downto 0));
 
 
 
	end generate branching_invfunc;
 
	branchingHighLander:
	if functype="SQUARE_ROOT" generate
		chiefQ <= (others => '0');
	end generate branchingHighLander;
 
	--! Inverse
	inverseDistanceOK:
	if functype="INVERSION" generate
 
		inverseDistance:
		process (clk,rst)
		begin
 
			if rst=rstMasterValue then
				iDistN <= (others => '0');
				iDistF <= (others => '0');
			elsif clk'event and clk='1' then
				iDistN <= chiefN;
				iDistF <= chiefQ;
			end if; 
 
 
		end process inverseDistance;
 
		inverseShifter: RLshifter
		generic map("INVERSION",c3width,iwidth,17)
		port map(
			iDistN,
			iDistF,
			inv);
	end generate inverseDistanceOK;
 
	inverseDistanceNOTOK:
	if functype = "SQUARE_ROOT" generate
		iDistN <= (others => '0');
		iDistF <= (others => '0');
		inv <= (others => '0');
	end generate inverseDistanceNOTOK;
 
end sqrtdiv_arch;
 
 
 
 
 
 
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.