---------------------------------------------------------------------------------- -- Company: -- Engineer: A.Kurka -- -- Create Date: 16.05.2021 -- modified : 16.05.2021 A.K -- Module Name: func_c - Behavioral -- Project Name: AS21 -- Target Devices: -- Tool versions: ISE 14.7 -- Description: Funktion für cosFP -- func_c[0,PI^2] = (P0 + X*(P1 + X*P2)) / (Q0 + X*(Q1 + X*Q2)); -- cos(X) = func_c(X^2); ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity func_c is port( nrst : in std_logic; clk : in std_logic; cefktC : in std_logic; -- startimpuls afkt Xinp : in std_logic_vector(31 downto 0); -- Input in [0, 0.5] in FP-Format aout : OUT std_logic_vector(31 downto 0) -- Output in [1, 1.047197+] in FP-Format, 1.047197=2*asin(0.5) ); end func_c; architecture Behavioral of func_c is ---------------------------------------------------- COMPONENT mulFP IS port ( a: IN std_logic_VECTOR(31 downto 0); b: IN std_logic_VECTOR(31 downto 0); clk: IN std_logic; ce: IN std_logic; result: OUT std_logic_VECTOR(31 downto 0)); END COMPONENT; --------------------------------------------- COMPONENT addFP IS port ( a: IN std_logic_VECTOR(31 downto 0); b: IN std_logic_VECTOR(31 downto 0); clk: IN std_logic; ce: IN std_logic; result: OUT std_logic_VECTOR(31 downto 0)); END COMPONENT; ------------------------------------------------------------ COMPONENT divFP IS port ( a: IN std_logic_VECTOR(31 downto 0); b: IN std_logic_VECTOR(31 downto 0); clk: IN std_logic; ce: IN std_logic; result: OUT std_logic_VECTOR(31 downto 0)); END COMPONENT; ----------------------------------------------------- TYPE T_PQTab IS ARRAY(0 TO 3) OF std_logic_vector(31 DOWNTO 0); -- Koeff Tabelle --koeffizienten Tabellen für P , MinMax Approximation CONSTANT PTab :T_PQTab:= -- alle werte in FP ( X"4859d8dc",--P0 + index 0 X"c7cc8cac",--P1 - X"45bb6448",--P2 + index 2 X"c29c3bf6" ); -------------------------------- CONSTANT QTab :T_PQTab:= -- alle werte in FP ( X"4859d8dc",--Q0 +1039.057684548 index 0 X"45d4c345",--Q1 +46.49394241313 X"42d3bc9b",--Q2 +1.0 indesx 2 X"3f800000" ); --==================== Signale für afkt ================================== SIGNAL statefktC :integer range 0 to 7:= 0; --SIGNAL ceafkt :std_logic:='0';-- Startimpuls afkt, extern SIGNAL ce1 :std_logic:='0';-- Start Pmul = Xinp*Pinp; Qmul = Xinp*Qinp SIGNAL ce2 :std_logic:='0';-- Start Padd = Pmul+PKoeff; Qadd = Qmul+QKoeff SIGNAL ce3 :std_logic:='0';-- Start Pplus/Qplus zuweisung SIGNAL ce4 :std_logic:='0';-- Start aout = Pplus/Qplus SIGNAL Pinp :std_logic_vector(31 DOWNTO 0):=X"00000000";-- 2. Input cPmul SIGNAL Qinp :std_logic_vector(31 DOWNTO 0):=X"00000000";-- 2. input cQmul SIGNAL Pmul :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPmul SIGNAL Qmul :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cQmul SIGNAL Pplus :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPmul SIGNAL Qplus :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cQmul SIGNAL Pa :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPadd SIGNAL Qa :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPadd SIGNAL Padd :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPadd, Ergebnis Auswertung P() SIGNAL Qadd :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cQadd, Ergebnis Auswertung Q() SIGNAL PKoeff :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Koeff von P() SIGNAL QKoeff :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Koeff von Q() --================================================================ --========================================================================== begin --================================================================= --************************************************************************ pfkt_C:PROCESS(clk) -- Process für fktC(Xinp) für cosFP berechnung. -- Loop Counter läuft von 1 = MAX(deg_P,deg_Q) - 1 bis 0 und dient -- als Index in PTab und QTab. VARIABLE TabIdx : INTEGER RANGE 0 TO 3 := 0; VARIABLE count :INTEGER RANGE 0 TO 7; BEGIN IF rising_edge(clk) THEN IF nrst = '0' THEN TabIdx := 0; -- just 0's PKoeff <= X"00000000"; -- Not-a-Number QKoeff <= X"00000000"; -- Not-a-Number Pinp <= X"00000000"; -- Not-a-Number Qinp <= X"00000000"; -- Not-a-Number ce1 <= '0'; ce2 <= '0'; ce4 <= '0'; count := 0; statefktC <= 0; ELSE CASE statefktC IS WHEN 0 => -- Start afkt IF cefktC = '1' THEN TabIdx := 3; -- Init Index in Tabellen (1 = max. Polynomgrad - 1)--****************. Pinp <= PTab(3); -- Init Pinp = PTab(2), (2 = max. Polynomgrad) Qinp <= QTab(3); -- Init Qinp = QTab(2), (2 = max. Polynomgrad) ce1 <= '1';--starten mul ce2 <= '0'; ce3 <= '0'; ce4 <= '0'; statefktC <= 1;-- Dann Auswertung gestartet ELSE Padd <= X"00000000"; Qadd <= X"00000000"; statefktC <= 0; END IF; --------------------------------- WHEN 1 => -- ausführen mul : Xinp * Ptab(2),Xinp * Qtab(2), ce1 <= '0'; -- reset ce2 <= '1'; -- start add -- Pmul,Qmul sind bereit -- Decrement Tab-Index TabIdx := TabIdx - 1; PKoeff <= PTab(TabIdx); QKoeff <= QTab(TabIdx); statefktC <= 2; WHEN 2 => -- add = Pmul + PKoeff ce2 <= '0'; -- reset IF TabIdx = 0 THEN -- letzte schlaufen Addition,zu P0,Q0 Addition Padd <= Pmul;--input für Add 2 setzen Qadd <= Qmul; ce3 <= '1'; --start Pplus Qplus statefktC <= 4; ELSE statefktC <= 3; END IF; WHEN 3 => Padd <= Pa; Qadd <= Qa; Pinp <= Pa; Qinp <= Qa; ce1 <= '1'; statefktC <= 1; WHEN 4 => --Run Add p0,q0 ce3 <= '0'; ce4 <= '1'; --start für div P/Q div Count := 1; statefktC <= 5; -- und warten auf Neustart WHEN 5 => IF count > 0 THEN count := count - 1; ce4 <= '0'; statefktC <= 5; ELSE statefktC <= 0; END IF; WHEN OTHERS => statefktC <= 0; END CASE; -- stateafkt END IF; -- nrst END IF; --clk END PROCESS; --end pafkt --=========Components Implementation==================================== -- ce1 cPmul: mulFP port map(a=>Xinp, b=>Pinp, clk=>clk, ce=>ce1, result=>Pmul); cQmul: mulFP port map(a=>Xinp, b=>Qinp, clk=>clk, ce=>ce1, result=>Qmul); -- ce2 cPadd: addFP port map(a=>Pmul, b=>PKoeff, clk=>clk, ce=>ce2, result=>Pa);-- cQadd: addFP port map(a=>Qmul, b=>QKoeff, clk=>clk, ce=>ce2, result=>Qa);-- -- cPplus könnte man sich zwahr sparen, in dem cPadd zweimal verwendet wird -- daführ kostet es ein CLK mehr -- ce3 cPplus: addFP port map(a=>Padd, b=>PKoeff, clk=>clk, ce=>ce3, result=>Pplus);-- cQplus: addFP port map(a=>Qadd, b=>QKoeff, clk=>clk, ce=>ce3, result=>Qplus);-- -- ce4 cPQdiv: divFP port map(a=>Pplus, b=>Qplus, clk=>clk, ce=>ce4, result=>aout); end Behavioral;