LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith; USE ieee.std_logic_signed.all; ENTITY cordic IS GENERIC( breite : integer := 12); PORT( phase : IN std_logic_vector (breite-1 DOWNTO 0); clk,rst : In std_logic; sinout, cosout : OUT std_logic_vector(9 DOWNTO 0) ); END cordic; -- Eingang: Phase 12 Bits -- Ausgang: sin cos 10 Bits -- CORDIC Gain Konstante: 010011011011 ~=0.60725 ARCHITECTURE nochmal OF cordic IS signal costemp, sintemp, controlI,controlQ : std_logic_vector (9 DOWNTO 0); signal angle : std_logic_vector (breite-1 DOWNTO 0); signal count : std_logic_vector (3 DOWNTO 0); signal L : integer; signal operation : std_logic; BEGIN PROCESS(clk,rst) variable z, z_temp,data : std_logic_vector (breite-1 DOWNTO 0); variable I_shift,Q_shift,I_temp,Q_temp,I,Q : std_logic_vector (9 DOWNTO 0); BEGIN IF (rst ='1') THEN -- Anfangswinkel einstellen IF (phase<"110000000000") THEN angle<="110000000000"; -- auf 0 - j1 costemp<="0000000000"; sintemp<="1000000000"; ELSIF (phase>"010000000000") THEN angle<="010000000000"; -- auf 0 + j1 costemp<="0000000000"; sintemp<="0111111111"; ELSE angle<="000000000000"; -- auf 1 + j0 costemp<="0111111111"; sintemp<="0000000000"; END IF; count<="0000"; ELSIF(clk'EVENT AND clk='1') THEN --------- Laden des nächsten Winkels --------- shift Werte CASE count IS WHEN "0000" => data := "001000000000"; -- 45.0000° I_shift:= (costemp(9) & costemp(9 DOWNTO 1)); Q_shift:= (sintemp(9) & sintemp(9 DOWNTO 1)); L<=1; WHEN "0001" => data := "000100101110"; -- 26.5650° I_shift:= (costemp(9) & costemp(9) & costemp(9 DOWNTO 2)); Q_shift:= (sintemp(9) & sintemp(9) & sintemp(9 DOWNTO 2)); L<=2; WHEN "0010" => data := "000010011111"; -- 14.0362° I_shift:= (costemp(9) & costemp(9) & costemp(9) & costemp(9 DOWNTO 3)); Q_shift:= (sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9 DOWNTO 3)); L<=3; WHEN "0011" => data := "000001010001"; -- 7.1250° I_shift:= (costemp(9) & costemp(9) & costemp(9) & costemp(9) & costemp(9 DOWNTO 4)); Q_shift:= (sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9 DOWNTO 4)); L<=4; WHEN "0100" => data := "000000101000"; -- 3.5763° I_shift:= (costemp(9) & costemp(9) & costemp(9) & costemp(9) & costemp(9) & costemp(9 DOWNTO 5)); Q_shift:= (sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9 DOWNTO 5)); L<=5; WHEN "0101" => data := "000000010011"; -- 1.7899° I_shift:= (costemp(9) & costemp(9) & costemp(9) & costemp(9) & costemp(9) & costemp(9) & costemp(9 DOWNTO 6)); Q_shift:= (sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9 DOWNTO 6)); L<=6; WHEN "0110" => data := "000000001010"; -- 0.8951° I_shift:= (costemp(9) & costemp(9) & costemp(9) & costemp(9) & costemp(9) & costemp(9) & costemp(9) & costemp(9 DOWNTO 7)); Q_shift:= (sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9 DOWNTO 7)); L<=7; WHEN "0111" => data := "000000000101"; -- 0.4476° I_shift:= (costemp(9) & costemp(9) & costemp(9) & costemp(9) & costemp(9) & costemp(9) & costemp(9) & costemp(9) & costemp(9 DOWNTO 8)); Q_shift:= (sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9) & sintemp(9 DOWNTO 8)); L<=8; WHEN OTHERS => data := "000000000000"; I_shift:= costemp; Q_shift:= sintemp; END CASE; IF count = "1000" THEN -- vorher noch cordic gain! cosout <= costemp; sinout <= sintemp; ELSE I := costemp; Q := sintemp; z := angle; controlI<=I_shift; controlQ<=Q_shift; IF((phase - z)>0)THEN -- rotiere positiv -- Ic_neu = Ic - (2^-L)·Qc -- Qc_neu = Qc + (2^-L)·Ic -- addiere die I,Q Werte mit den geshifteten -- gib es auf die Ausgänge I_temp := I - Q_shift; Q_temp := Q + I_shift; z_temp:= z + data; costemp<=I_temp; sintemp<=Q_temp; angle<=z_temp; operation<='0'; ELSIF((phase - z)<0) THEN -- rotiere negativ -- Ic_neu = Ic + (2^-L)·Qc -- Qc_neu = Qc - (2^-L)·Ic -- addiere die I,Q Werte mit den geshifteten -- gib es auf die Ausgänge I_temp := I + Q_shift; Q_temp := Q - I_shift; z_temp:= z - data; costemp<=I_temp; sintemp<=Q_temp; angle<=z_temp; operation <='1'; END IF; count <= count + 1; END IF; END IF; END PROCESS; END nochmal;