?? cordic_-
字號:
------------------------------------------------------------------------
-- Title CORDIC calculater sin(x), cos(x), atan(y/x) --
-- File CORDIC.vhd --
-- Entity CORDIC --
-- rev date coded contents --
-- 001 99/01/06 ueno Make Original --
------------------------------------------------------------------------
library ieee ;
use ieee.std_logic_1164.all ;
use ieee.std_logic_unsigned.all ;
--use IEEE.std_logic_signed.all ;
--use IEEE.std_logic_arith.all ;
------------------------------------------------------------------------
-- entity --
------------------------------------------------------------------------
entity CORDIC is
port(
-- Input/Output Data format = Fixed Point Value
-- range -1.99994 to 1.99994 2's complement
-- 15 14 . 13 12 11 10 09 08 07 06 05 04 03 02 01 00
-- Sign ^point
--
IN_X : in std_logic_vector(15 downto 0) ; -- atan(y/X) -0.15 to 1.00
IN_Y : in std_logic_vector(15 downto 0) ; -- atan(Y/x) -1.00 to 1.00
IN_ANGLE : in std_logic_vector(15 downto 0) ; -- angle(thita) -1.74 to 1.74
IN_START : in std_logic ; -- convert start
IN_MODE : in std_logic ; -- 1=atan/0=sin,cos
CLK : in std_logic ; -- System Clock
ENABLE : in std_logic ; -- Clock Enable
XRST : in std_logic ; -- Reset
OUT_FINISH : out std_logic ; -- Convert end
OUT_X : out std_logic_vector(15 downto 0) ; -- Calculate X
OUT_Y : out std_logic_vector(15 downto 0) ; -- Calculate Y
OUT_Z : out std_logic_vector(15 downto 0) -- Calculate Z
);
end CORDIC ;
------------------------------------------------------------------------
-- architecture --
------------------------------------------------------------------------
architecture RTL of CORDIC is
--constant ENABLE : std_logic := '1' ;
-----------------------------------------------------------
-- Constants --
-----------------------------------------------------------
constant VAL0 : std_logic_vector(15 downto 0) := "0000000000000000" ; -- 0.000000000
constant VALX : std_logic_vector(15 downto 0) := "0010011011011101" ; -- 0.607252935
constant ATAN00 : std_logic_vector(15 downto 0) := "0011001001000100" ; -- atan(1/1)
constant ATAN01 : std_logic_vector(15 downto 0) := "0001110110101100" ; -- atan(1/2)
constant ATAN02 : std_logic_vector(15 downto 0) := "0000111110101110" ; -- atan(1/4)
constant ATAN03 : std_logic_vector(15 downto 0) := "0000011111110101" ; -- atan(1/8)
constant ATAN04 : std_logic_vector(15 downto 0) := "0000001111111111" ; -- atan(1/16)
constant ATAN05 : std_logic_vector(15 downto 0) := "0000001000000000" ; -- atan(1/32)
constant ATAN06 : std_logic_vector(15 downto 0) := "0000000100000000" ; -- atan(1/64)
constant ATAN07 : std_logic_vector(15 downto 0) := "0000000010000000" ; -- atan(1/128)
constant ATAN08 : std_logic_vector(15 downto 0) := "0000000001000000" ; -- atan(1/256)
constant ATAN09 : std_logic_vector(15 downto 0) := "0000000000100000" ; -- atan(1/512)
constant ATAN10 : std_logic_vector(15 downto 0) := "0000000000010000" ; -- atan(1/1024)
constant ATAN11 : std_logic_vector(15 downto 0) := "0000000000001000" ; -- atan(1/2048)
constant ATAN12 : std_logic_vector(15 downto 0) := "0000000000000100" ; -- atan(1/4096)
constant ATAN13 : std_logic_vector(15 downto 0) := "0000000000000010" ; -- atan(1/8192)
constant ATAN14 : std_logic_vector(15 downto 0) := "0000000000000001" ; -- atan(1/16384)
constant ATAN15 : std_logic_vector(15 downto 0) := "0000000000000000" ; -- atan(1/32768)
-----------------------------------------------------------
-- Signals --
-----------------------------------------------------------
signal REG_X : std_logic_vector(15 downto 0) ; -- Xn Register
signal REG_Y : std_logic_vector(15 downto 0) ; -- Yn Register
signal REG_Z : std_logic_vector(15 downto 0) ; -- Zn Register
signal REG_J : std_logic_vector(3 downto 0) ; -- 0 to 15 counter
signal AX : std_logic_vector(15 downto 0) ; -- Ballel Shift X
signal BX : std_logic_vector(15 downto 0) ; -- Ballel Shift X
signal CX : std_logic_vector(15 downto 0) ; -- Ballel Shift X
signal DX : std_logic_vector(15 downto 0) ; -- Ballel Shift X
signal AY : std_logic_vector(15 downto 0) ; -- Ballel Shift Y
signal BY : std_logic_vector(15 downto 0) ; -- Ballel Shift Y
signal CY : std_logic_vector(15 downto 0) ; -- Ballel Shift Y
signal DY : std_logic_vector(15 downto 0) ; -- Ballel Shift Y
signal TAB_Z : std_logic_vector(15 downto 0) ; -- Table Select Z
signal INIT_LOAD : std_logic ; -- X,Y,Z Initialize
signal NOW_CONVERT : std_logic ; -- Now Conveting for CORDIC
signal ADD_SUB : std_logic ; -- Next Calculate '1'=ADD/'0'=SUB
-----------------------------------------------------------
-- Architectures --
-----------------------------------------------------------
begin
-----------------------------------------------------------
-- Flag Control --
-----------------------------------------------------------
INIT_FLAG : process( CLK, XRST )
begin
if( XRST='0' ) then
INIT_LOAD <= '0' ;
elsif( CLK'event and CLK='1' ) then
if( ENABLE='1' ) then
if( IN_START='1' and INIT_LOAD='0' and NOW_CONVERT='0' ) then
INIT_LOAD <= '1' ;
else
INIT_LOAD <= '0' ;
end if ;
end if ;
end if ;
end process ;
CONVERT_FLAG : process( CLK, XRST )
begin
if( XRST='0' ) then
NOW_CONVERT <= '0' ;
elsif( CLK'event and CLK='1' ) then
if( ENABLE='1' ) then
if( INIT_LOAD='1' ) then
NOW_CONVERT <= '1' ;
elsif( REG_J="1111" ) then
NOW_CONVERT <= '0' ;
end if ;
end if ;
end if ;
end process ;
-----------------------------------------------------------
-- Sequence Counter --
-----------------------------------------------------------
COUNTER_GEN : process( CLK, XRST )
begin
if( XRST='0' ) then
REG_J <= "0000" ;
elsif( CLK'event and CLK='1' ) then
if( ENABLE='1' ) then
if( NOW_CONVERT='1' ) then
REG_J <= REG_J + 1 ;
end if ;
end if ;
end if ;
end process ;
-----------------------------------------------------------
-- ADD/SUB Flag --
-----------------------------------------------------------
SELECT_ADD_SUB : ADD_SUB <= not REG_Y(15) when IN_MODE='1' else REG_Z(15) ;
-----------------------------------------------------------
-- Ballel Shifter --
-----------------------------------------------------------
BALLEL_AX : process( REG_X, REG_J )
begin
if( REG_J(3)='1' ) then
AX <= REG_X(15) & REG_X(15) & REG_X(15) & REG_X(15) & REG_X(15) & REG_X(15) & REG_X(15) & REG_X(15) & REG_X(15 downto 8);
else
AX <= REG_X ;
end if ;
end process ;
BALLEL_BX : process( AX, REG_J )
begin
if( REG_J(2)='1' ) then
BX <= AX(15) & AX(15) & AX(15) & AX(15) & AX(15 downto 4);
else
BX <= AX ;
end if ;
end process ;
BALLEL_CX : process( BX, REG_J )
begin
if( REG_J(1)='1' ) then
CX <= BX(15) & BX(15) & BX(15 downto 2);
else
CX <= BX ;
end if ;
end process ;
BALLEL_DX : process( CX, REG_J )
begin
if( REG_J(0)='1' ) then
DX <= CX(15) & CX(15 downto 1);
else
DX <= CX ;
end if ;
end process ;
BALLEL_AY : process( REG_Y, REG_J )
begin
if( REG_J(3)='1' ) then
AY <= REG_Y(15) & REG_Y(15) & REG_Y(15) & REG_Y(15) & REG_Y(15) & REG_Y(15) & REG_Y(15) & REG_Y(15) & REG_Y(15 downto 8);
else
AY <= REG_Y ;
end if ;
end process ;
BALLEL_BY : process( AY, REG_J )
begin
if( REG_J(2)='1' ) then
BY <= AY(15) & AY(15) & AY(15) & AY(15) & AY(15 downto 4);
else
BY <= AY ;
end if ;
end process ;
BALLEL_CY : process( BY, REG_J )
begin
if( REG_J(1)='1' ) then
CY <= BY(15) & BY(15) & BY(15 downto 2);
else
CY <= BY ;
end if ;
end process ;
BALLEL_DY : process( CY, REG_J )
begin
if( REG_J(0)='1' ) then
DY <= CY(15) & CY(15 downto 1);
else
DY <= CY ;
end if ;
end process ;
TABLE_Z : process( REG_J )
begin
case REG_J is
when "0000" => TAB_Z <= ATAN00 ;
when "0001" => TAB_Z <= ATAN01 ;
when "0010" => TAB_Z <= ATAN02 ;
when "0011" => TAB_Z <= ATAN03 ;
when "0100" => TAB_Z <= ATAN04 ;
when "0101" => TAB_Z <= ATAN05 ;
when "0110" => TAB_Z <= ATAN06 ;
when "0111" => TAB_Z <= ATAN07 ;
when "1000" => TAB_Z <= ATAN08 ;
when "1001" => TAB_Z <= ATAN09 ;
when "1010" => TAB_Z <= ATAN10 ;
when "1011" => TAB_Z <= ATAN11 ;
when "1100" => TAB_Z <= ATAN12 ;
when "1101" => TAB_Z <= ATAN13 ;
when "1110" => TAB_Z <= ATAN14 ;
when "1111" => TAB_Z <= ATAN15 ;
when others => TAB_Z <= VAL0 ;
end case ;
end process ;
-----------------------------------------------------------
-- Calculate --
-----------------------------------------------------------
CALC_X : process( CLK, XRST )
begin
if( XRST='0') then
REG_X <= (others=>'0') ;
elsif( CLK'event and CLK='1' ) then
if( ENABLE='1' ) then
-- Initial Value
if( INIT_LOAD = '1' ) then
if( IN_MODE='1' ) then
-- Atan Mode
REG_X <= IN_X ;
else
-- Sin/Cos Mode
REG_X <= VALX ;
end if ;
elsif( NOW_CONVERT='1' ) then
if( ADD_SUB='1' ) then
REG_X <= REG_X + DY ;
else
REG_X <= REG_X - DY ;
end if ;
end if ;
end if ;
end if ;
end process ;
CALC_Y : process( CLK, XRST )
begin
if( XRST='0') then
REG_Y <= (others=>'0') ;
elsif( CLK'event and CLK='1' ) then
if( ENABLE='1' ) then
-- Initial Value
if( INIT_LOAD = '1' ) then
if( IN_MODE='1' ) then
-- Atan Mode
REG_Y <= IN_Y ;
else
-- Sin/Cos Mode
REG_Y <= VAL0 ;
end if ;
elsif( NOW_CONVERT='1' ) then
if( ADD_SUB='1' ) then
REG_Y <= REG_Y - DX ;
else
REG_Y <= REG_Y + DX ;
end if ;
end if ;
end if ;
end if ;
end process ;
CALC_Z : process( CLK, XRST )
begin
if( XRST='0') then
REG_Z <= (others=>'0') ;
elsif( CLK'event and CLK='1' ) then
if( ENABLE='1' ) then
-- Initial Value
if( INIT_LOAD = '1' ) then
if( IN_MODE='1' ) then
-- Atan Mode
REG_Z <= VAL0 ;
else
-- Sin/Cos Mode
REG_Z <= IN_ANGLE ;
end if ;
elsif( NOW_CONVERT='1' ) then
if( ADD_SUB='1' ) then
REG_Z <= REG_Z + TAB_Z ;
else
REG_Z <= REG_Z - TAB_Z ;
end if ;
end if ;
end if ;
end if ;
end process ;
OUT_FINISH <= not NOW_CONVERT ;
OUT_X <= REG_X ;
OUT_Y <= REG_Y ;
OUT_Z <= REG_Z ;
end RTL ;
------------------------------------------------------------------------
-- End of File --
------------------------------------------------------------------------
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -