1 | ----------------------------------------------------------------------------------
|
2 | -- Company:
|
3 | -- Engineer: A.Kurka
|
4 | --
|
5 | -- Create Date: 16.05.2021
|
6 | -- modified : 16.05.2021 A.K
|
7 | -- Module Name: func_c - Behavioral
|
8 | -- Project Name: AS21
|
9 | -- Target Devices:
|
10 | -- Tool versions: ISE 14.7
|
11 | -- Description: Funktion für cosFP
|
12 | -- func_c[0,PI^2] = (P0 + X*(P1 + X*P2)) / (Q0 + X*(Q1 + X*Q2));
|
13 | -- cos(X) = func_c(X^2);
|
14 | ----------------------------------------------------------------------------------
|
15 | library IEEE;
|
16 | use IEEE.STD_LOGIC_1164.ALL;
|
17 | use IEEE.STD_LOGIC_ARITH.ALL;
|
18 | use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
19 |
|
20 |
|
21 | entity func_c is
|
22 | port( nrst : in std_logic;
|
23 | clk : in std_logic;
|
24 | cefktC : in std_logic; -- startimpuls afkt
|
25 | Xinp : in std_logic_vector(31 downto 0); -- Input in [0, 0.5] in FP-Format
|
26 | aout : OUT std_logic_vector(31 downto 0) -- Output in [1, 1.047197+] in FP-Format, 1.047197=2*asin(0.5)
|
27 | );
|
28 | end func_c;
|
29 |
|
30 | architecture Behavioral of func_c is
|
31 | ----------------------------------------------------
|
32 | COMPONENT mulFP IS
|
33 | port (
|
34 | a: IN std_logic_VECTOR(31 downto 0);
|
35 | b: IN std_logic_VECTOR(31 downto 0);
|
36 | clk: IN std_logic;
|
37 | ce: IN std_logic;
|
38 | result: OUT std_logic_VECTOR(31 downto 0));
|
39 | END COMPONENT;
|
40 | ---------------------------------------------
|
41 | COMPONENT addFP IS
|
42 | port (
|
43 | a: IN std_logic_VECTOR(31 downto 0);
|
44 | b: IN std_logic_VECTOR(31 downto 0);
|
45 | clk: IN std_logic;
|
46 | ce: IN std_logic;
|
47 | result: OUT std_logic_VECTOR(31 downto 0));
|
48 | END COMPONENT;
|
49 | ------------------------------------------------------------
|
50 | COMPONENT divFP IS
|
51 | port (
|
52 | a: IN std_logic_VECTOR(31 downto 0);
|
53 | b: IN std_logic_VECTOR(31 downto 0);
|
54 | clk: IN std_logic;
|
55 | ce: IN std_logic;
|
56 | result: OUT std_logic_VECTOR(31 downto 0));
|
57 | END COMPONENT;
|
58 | -----------------------------------------------------
|
59 | TYPE T_PQTab IS ARRAY(0 TO 3) OF std_logic_vector(31 DOWNTO 0); -- Koeff Tabelle
|
60 | --koeffizienten Tabellen für P , MinMax Approximation
|
61 | CONSTANT PTab :T_PQTab:= -- alle werte in FP
|
62 | (
|
63 | X"4859d8dc",--P0 + index 0
|
64 | X"c7cc8cac",--P1 -
|
65 | X"45bb6448",--P2 + index 2
|
66 | X"c29c3bf6"
|
67 | );
|
68 | --------------------------------
|
69 | CONSTANT QTab :T_PQTab:= -- alle werte in FP
|
70 | (
|
71 | X"4859d8dc",--Q0 +1039.057684548 index 0
|
72 | X"45d4c345",--Q1 +46.49394241313
|
73 | X"42d3bc9b",--Q2 +1.0 indesx 2
|
74 | X"3f800000"
|
75 | );
|
76 | --==================== Signale für afkt ==================================
|
77 | SIGNAL statefktC :integer range 0 to 7:= 0;
|
78 | --SIGNAL ceafkt :std_logic:='0';-- Startimpuls afkt, extern
|
79 | SIGNAL ce1 :std_logic:='0';-- Start Pmul = Xinp*Pinp; Qmul = Xinp*Qinp
|
80 | SIGNAL ce2 :std_logic:='0';-- Start Padd = Pmul+PKoeff; Qadd = Qmul+QKoeff
|
81 | SIGNAL ce3 :std_logic:='0';-- Start Pplus/Qplus zuweisung
|
82 | SIGNAL ce4 :std_logic:='0';-- Start aout = Pplus/Qplus
|
83 | SIGNAL Pinp :std_logic_vector(31 DOWNTO 0):=X"00000000";-- 2. Input cPmul
|
84 | SIGNAL Qinp :std_logic_vector(31 DOWNTO 0):=X"00000000";-- 2. input cQmul
|
85 |
|
86 | SIGNAL Pmul :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPmul
|
87 | SIGNAL Qmul :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cQmul
|
88 | SIGNAL Pplus :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPmul
|
89 | SIGNAL Qplus :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cQmul
|
90 | SIGNAL Pa :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPadd
|
91 | SIGNAL Qa :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPadd
|
92 | SIGNAL Padd :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPadd, Ergebnis Auswertung P()
|
93 | SIGNAL Qadd :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cQadd, Ergebnis Auswertung Q()
|
94 | SIGNAL PKoeff :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Koeff von P()
|
95 | SIGNAL QKoeff :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Koeff von Q()
|
96 | --================================================================
|
97 |
|
98 | --==========================================================================
|
99 | begin
|
100 | --=================================================================
|
101 | --************************************************************************
|
102 | pfkt_C:PROCESS(clk) -- Process für fktC(Xinp) für cosFP berechnung.
|
103 | -- Loop Counter läuft von 1 = MAX(deg_P,deg_Q) - 1 bis 0 und dient
|
104 | -- als Index in PTab und QTab.
|
105 |
|
106 | VARIABLE TabIdx : INTEGER RANGE 0 TO 3 := 0;
|
107 | VARIABLE count :INTEGER RANGE 0 TO 7;
|
108 | BEGIN
|
109 | IF rising_edge(clk) THEN
|
110 | IF nrst = '0' THEN
|
111 | TabIdx := 0; -- just 0's
|
112 | PKoeff <= X"00000000"; -- Not-a-Number
|
113 | QKoeff <= X"00000000"; -- Not-a-Number
|
114 | Pinp <= X"00000000"; -- Not-a-Number
|
115 | Qinp <= X"00000000"; -- Not-a-Number
|
116 | ce1 <= '0';
|
117 | ce2 <= '0';
|
118 | ce4 <= '0';
|
119 | count := 0;
|
120 | statefktC <= 0;
|
121 | ELSE
|
122 | CASE statefktC IS
|
123 | WHEN 0 => -- Start afkt
|
124 | IF cefktC = '1' THEN
|
125 | TabIdx := 3; -- Init Index in Tabellen (1 = max. Polynomgrad - 1)--****************.
|
126 | Pinp <= PTab(3); -- Init Pinp = PTab(2), (2 = max. Polynomgrad)
|
127 | Qinp <= QTab(3); -- Init Qinp = QTab(2), (2 = max. Polynomgrad)
|
128 | ce1 <= '1';--starten mul
|
129 | ce2 <= '0';
|
130 | ce3 <= '0';
|
131 | ce4 <= '0';
|
132 | statefktC <= 1;-- Dann Auswertung gestartet
|
133 | ELSE
|
134 | Padd <= X"00000000";
|
135 | Qadd <= X"00000000";
|
136 | statefktC <= 0;
|
137 | END IF;
|
138 | ---------------------------------
|
139 | WHEN 1 => -- ausführen mul : Xinp * Ptab(2),Xinp * Qtab(2),
|
140 | ce1 <= '0'; -- reset
|
141 | ce2 <= '1'; -- start add
|
142 | -- Pmul,Qmul sind bereit
|
143 | -- Decrement Tab-Index
|
144 | TabIdx := TabIdx - 1;
|
145 | PKoeff <= PTab(TabIdx);
|
146 | QKoeff <= QTab(TabIdx);
|
147 | statefktC <= 2;
|
148 | WHEN 2 => -- add = Pmul + PKoeff
|
149 | ce2 <= '0'; -- reset
|
150 | IF TabIdx = 0 THEN
|
151 | -- letzte schlaufen Addition,zu P0,Q0 Addition
|
152 | Padd <= Pmul;--input für Add 2 setzen
|
153 | Qadd <= Qmul;
|
154 | ce3 <= '1'; --start Pplus Qplus
|
155 | statefktC <= 4;
|
156 | ELSE
|
157 | statefktC <= 3;
|
158 | END IF;
|
159 | WHEN 3 =>
|
160 | Padd <= Pa;
|
161 | Qadd <= Qa;
|
162 | Pinp <= Pa;
|
163 | Qinp <= Qa;
|
164 | ce1 <= '1';
|
165 | statefktC <= 1;
|
166 | WHEN 4 => --Run Add p0,q0
|
167 | ce3 <= '0';
|
168 | ce4 <= '1'; --start für div P/Q div
|
169 | Count := 1;
|
170 | statefktC <= 5; -- und warten auf Neustart
|
171 | WHEN 5 =>
|
172 | IF count > 0 THEN
|
173 | count := count - 1;
|
174 | ce4 <= '0';
|
175 | statefktC <= 5;
|
176 | ELSE
|
177 | statefktC <= 0;
|
178 | END IF;
|
179 | WHEN OTHERS =>
|
180 | statefktC <= 0;
|
181 | END CASE; -- stateafkt
|
182 | END IF; -- nrst
|
183 | END IF; --clk
|
184 | END PROCESS; --end pafkt
|
185 |
|
186 |
|
187 | --=========Components Implementation====================================
|
188 | -- ce1
|
189 | cPmul: mulFP port map(a=>Xinp, b=>Pinp, clk=>clk, ce=>ce1, result=>Pmul);
|
190 | cQmul: mulFP port map(a=>Xinp, b=>Qinp, clk=>clk, ce=>ce1, result=>Qmul);
|
191 | -- ce2
|
192 | cPadd: addFP port map(a=>Pmul, b=>PKoeff, clk=>clk, ce=>ce2, result=>Pa);--
|
193 | cQadd: addFP port map(a=>Qmul, b=>QKoeff, clk=>clk, ce=>ce2, result=>Qa);--
|
194 | -- cPplus könnte man sich zwahr sparen, in dem cPadd zweimal verwendet wird
|
195 | -- daführ kostet es ein CLK mehr
|
196 | -- ce3
|
197 | cPplus: addFP port map(a=>Padd, b=>PKoeff, clk=>clk, ce=>ce3, result=>Pplus);--
|
198 | cQplus: addFP port map(a=>Qadd, b=>QKoeff, clk=>clk, ce=>ce3, result=>Qplus);--
|
199 | -- ce4
|
200 | cPQdiv: divFP port map(a=>Pplus, b=>Qplus, clk=>clk, ce=>ce4, result=>aout);
|
201 |
|
202 |
|
203 |
|
204 | end Behavioral;
|