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

Subversion Repositories special_functions_unit

[/] [special_functions_unit/] [Open_source_SFU/] [cordic_vhdl/] [cordic.vhd] - Rev 4

Compare with Previous | Blame | View Log

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.numeric_std.all;
 
ENTITY cordic IS
	PORT(
			iClk		:in		std_logic;
			iReset		:in 	std_logic;
			istart		:in		std_logic;
			iEntrada	:in 	std_logic_vector(31 downto 0);
			oSalida1	:out	std_logic_vector(31 downto 0);
			oSalida2	:out	std_logic_vector(31 downto 0);
			oready		:out	std_logic
		);             
END cordic;
 
ARCHITECTURE RTL OF cordic IS
type estados is(s0,s1);
signal ep,ns:estados;
 
type memoria is array(0 to 19) of std_logic_vector(31 downto 0);
 
constant	Angulo  : memoria :=(
X"3F490FDB",
X"3EED6338",
X"3E7ADBB0",
X"3DFEADD5",
X"3D7FAADE",
X"3CFFEAAE",
X"3C7FFAAB",
X"3BFFFEAB",
X"3B7FFFAB",
X"3AFFFFEB",
X"3A7FFFFB",
X"39FFFFFF",
X"39800000",
X"39000000",
X"38800000",
X"38000000",
X"37800000",
X"37000000",
X"36800000",
X"36000000");
 
constant	Constante  : memoria :=(
X"3F800000",
X"3F000000",
X"3E800000",
X"3E000000",
X"3D800000",
X"3D000000",
X"3C800000",
X"3C000000",
X"3B800000",
X"3B000000",
X"3A800000",
X"3A000000",
X"39800000",
X"39000000",
X"38800000",
X"38000000",
X"37800000",
X"37000000",
X"36800000",
X"36000000");
 
signal X,Y,Z :std_logic_vector(31 downto 0);
signal xsub,yadd,zsub :std_logic_vector(31 downto 0);
signal prodx,prody :std_logic_vector(31 downto 0);
signal di2_i,diangulo :std_logic_vector(31 downto 0);
signal counteri :std_logic_vector(4 downto 0);
signal selx,enx,sely,eny,selz,enz,seli,eni :std_logic;
 
signal w_case_cos: std_logic_vector(31 downto 0);
signal w_case_sin: std_logic_vector(31 downto 0);
signal w_case_en: std_logic;
 
 
 
BEGIN
 
FP_SUB_X: entity work.suma_resta
	port map(operando1   =>unsigned(X),
			operando2	 =>unsigned(prodx),
			operacion	 =>"0010",
			std_logic_vector(resultado)	 =>xsub);
 
 
FP_ADD_Y: entity work.suma_resta
	port map(operando1   =>unsigned(Y),
			operando2	 =>unsigned(prody),
			operacion	 =>"0001",
			std_logic_vector(resultado)	 =>yadd);
 
FP_SUB_Z: entity work.suma_resta
	port map(operando1   =>unsigned(Z),
			operando2	 =>unsigned(diangulo),
			operacion	 =>"0010",
			std_logic_vector(resultado)	 =>zsub);
 
FP_MUL_X: entity work.multFP
	port map(entrada_x  => Y,
			 entrada_y	=> di2_i,	 
			 salida     => prodx);
 
FP_MUL_Y: entity work.multFP
	port map(entrada_x  => X,
			 entrada_y	=> di2_i,	 
			 salida     => prody);
 
 
di2_i <= (Constante(to_integer(unsigned(counteri)))(31) xor Z(31))&(Constante(to_integer(unsigned(counteri)))(30 downto 0));
diangulo <= (Angulo(to_integer(unsigned(counteri)))(31) xor Z(31))&(Angulo(to_integer(unsigned(counteri)))(30 downto 0));
 
 
Xreg:process(iClk,iReset)
	begin
		if iReset='0' then
			X <= (others=>'0');
		elsif rising_edge(iClk) then
			if enx='1' then
				if selx='1' then
					if w_case_en = '1' then
						X <= w_case_cos;
					else
						if(unsigned(X(30 downto 23))=127 and unsigned(X(22 downto 0))=0) then
							X <= X"3f800000";
						else
							X <= xsub;
						end if;						
					end if;
				else
					X <= X"3f1b74ee";
				end if;
			end if;
		end if;
	end process Xreg;
 
Yreg:process(iClk,iReset)
	begin
		if iReset='0' then
			Y <= (others=>'0');
		elsif rising_edge(iClk) then
			if eny='1' then
				if sely='1' then
					if w_case_en = '1' then
						Y <= w_case_sin;
					else
						if(unsigned(Y(30 downto 23))=127 and unsigned(Y(22 downto 0))=0) then
							Y <= X"3f800000";
						else
							Y <= yadd;
						end if;
					end if;
				else
					Y <= (others=>'0');
				end if;
			end if;
		end if;
	end process Yreg;
 
 
Zreg:process(iClk,iReset)
	begin
		if iReset='0' then
			Z <= (others=>'0');
		elsif rising_edge(iClk) then
			if enz='1' then
				if selz='1' then
					Z <= zsub;
				else
					Z <= iEntrada;
				end if;
			end if;
		end if;
	end process Zreg;
 
ireg:process(iClk,iReset)
	begin
		if iReset='0' then
			counteri <= (others=>'0');
		elsif rising_edge(iClk) then
			if eni='1' then
				if seli='1' then
					counteri <= std_logic_vector(unsigned(counteri)+1);
				else
					counteri <= (others=>'0');
				end if;
			end if;
		end if;
	end process ireg;
 
FSM_NS:process(istart,ep,counteri,w_case_en)
	begin
		case ep is
			when s0 =>
				if istart='1' then
					ns <= s1;
				else
					ns <= s0;
				end if;
			when s1 =>
				if unsigned(counteri)=16 or w_case_en='1' then
					ns <= s0;
				else
					ns <= s1;
				end if;
			when others=>
		end case;
	end process;
 
 
FSM_TS:process(iClk,iReset)
	begin
		if iReset='0' then
			ep <= s0;
		elsif rising_edge(iClk) then
			ep <= ns;
		end if;
	end process;
 
FSM_OUT:process(istart,ep,counteri,w_case_en)
	begin
		case ep is
			when s0 =>
				oready <= '1';
				if istart='1' then
					enx   <= '1';
					selx  <= '0';
					eny   <= '1';
					sely  <= '0';
					enz   <= '1';
					selz  <= '0';
					eni   <= '1';
					seli  <= '0';						
				else
					enx   <= '0';
					selx  <= '0';
					eny   <= '0';
					sely  <= '0';
					enz   <= '0';
					selz  <= '0';
					eni   <= '0';
					seli  <= '0';
				end if;
			when s1 =>
				oready <= '0';
				enx   <= '1';
				selx  <= '1';
				eny   <= '1';
				sely  <= '1';
				enz   <= '1';
				selz  <= '1';				
				if unsigned(counteri)=16 or w_case_en='1' then
					eni   <= '0';
					seli  <= '0';
				else
					eni   <= '1';
					seli  <= '1';
				end if;
			when others=>
				oready <= '0';
				enx   <= '0';
				selx  <= '0';
				eny   <= '0';
				sely  <= '0';
				enz   <= '0';
				selz  <= '0';
				eni   <= '0';
				seli  <= '0';
		end case;
	end process;
 
 
	IEEECASE: entity work.cordic_ieee
		port map(
		i_reset			=> iReset,
		i_clk			=> iClk,
		i_data			=> iEntrada,
		i_en			=> enx,
		i_sel			=> selx,
		o_case_cos		=> w_case_cos,
		o_case_sin		=> w_case_sin,
		o_case_en		=> w_case_en
		);
 
 
--	ieeeprocess: process(w_case_en)
 
--	begin
 
--		case w_case_en is
--		when '0'	=> oSalida1 <= X;			oSalida2 <= Y;
--		when '1' 	=> oSalida1 <= w_case_cos;	oSalida2 <= w_case_sin;
--		when others => oSalida1 <= X; 			oSalida2 <= Y;
--		end case;
 
--	end process;
 
	oSalida1 <= X;
	oSalida2 <= Y;
 
END RTL;

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.