1 | ----------------------------------------------------------------------------------
|
2 | -- Company:
|
3 | -- Engineer:a.Kurka
|
4 | --
|
5 | -- Create Date: 06.06.2021 by a.kurka
|
6 | -- Design Name: AS21
|
7 | -- Module Name: atanFP - Behavioral
|
8 | -- modified : 15.06.2021 by a.kurka
|
9 | --Berechnet arctang aus Xin / Yin für Bereich -PI .... PI
|
10 | -- output Winkel in rad FP Format, benötigt 20 clk
|
11 | -- dauer 22 clk
|
12 | ----------------------------------------------------------------------------------
|
13 | library IEEE;
|
14 | use IEEE.STD_LOGIC_1164.ALL;
|
15 | use IEEE.STD_LOGIC_ARITH.ALL;
|
16 | use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
17 |
|
18 |
|
19 | entity atanFP is
|
20 | port( nrst : in std_logic;
|
21 | clk : in std_logic;
|
22 | ceatan : in std_logic;-- startimpuls afkt
|
23 | Xinp :in std_logic_vector(31 downto 0);-- input X FP FP format
|
24 | Yinp :in std_logic_vector(31 downto 0);-- input Y FP FP format
|
25 | atanFP :OUT std_logic_vector(31 downto 0):=X"00000000"-- output Winkel(rad) in FP format
|
26 | );
|
27 | end atanFP;
|
28 |
|
29 | architecture Behavioral of atanFP is
|
30 | --=============================================
|
31 | COMPONENT afkt is
|
32 | generic( P0:std_logic_vector(31 downto 0):=X"00000000";
|
33 | P1:std_logic_vector(31 downto 0):=X"00000000";
|
34 | P2:std_logic_vector(31 downto 0):=X"00000000";
|
35 | Q0:std_logic_vector(31 downto 0):=X"00000000";
|
36 | Q1:std_logic_vector(31 downto 0):=X"00000000";
|
37 | Q2:std_logic_vector(31 downto 0):=X"00000000"
|
38 | );
|
39 | port( nrst : in std_logic;
|
40 | clk : in std_logic;
|
41 | ceafkt : in std_logic;-- startimpuls afkt
|
42 | Xinp :in std_logic_vector(31 downto 0);--input afkt FP format, immer positiv
|
43 | aout :OUT std_logic_vector(31 downto 0)-- output afkt FP format
|
44 | );
|
45 | END COMPONENT;
|
46 | ------------------------------------------------------------
|
47 | COMPONENT mulFP IS
|
48 | port (
|
49 | a: IN std_logic_VECTOR(31 downto 0);
|
50 | b: IN std_logic_VECTOR(31 downto 0);
|
51 | clk: IN std_logic;
|
52 | ce: IN std_logic;
|
53 | result: OUT std_logic_VECTOR(31 downto 0));
|
54 | END COMPONENT;
|
55 | ------------------------------------------------------------
|
56 | COMPONENT divFP IS
|
57 | port (
|
58 | a: IN std_logic_VECTOR(31 downto 0);
|
59 | b: IN std_logic_VECTOR(31 downto 0);
|
60 | clk: IN std_logic;
|
61 | ce: IN std_logic;
|
62 | result: OUT std_logic_VECTOR(31 downto 0)
|
63 | );
|
64 | END COMPONENT;
|
65 |
|
66 | ------------------------------------
|
67 | ----if a >= b then result = 1
|
68 | --COMPONENT compFP IS
|
69 | -- port (
|
70 | -- a: IN std_logic_VECTOR(31 downto 0);
|
71 | -- b: IN std_logic_VECTOR(31 downto 0);
|
72 | -- clk: IN std_logic;
|
73 | -- ce: IN std_logic;
|
74 | -- result: OUT std_logic_VECTOR(0 downto 0));
|
75 | --END COMPONENT;
|
76 | -----------------------------------------------
|
77 | -- if a > b then result = "0001"
|
78 | COMPONENT cmpgr IS
|
79 | PORT (
|
80 | a : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
|
81 | b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
|
82 | clk : IN STD_LOGIC;
|
83 | ce : IN STD_LOGIC;
|
84 | result : OUT STD_LOGIC_VECTOR(0 DOWNTO 0)
|
85 | );
|
86 | END COMPONENT;-- cmpgr;
|
87 | -----------------------------------------
|
88 | COMPONENT subFP IS
|
89 | port (
|
90 | a: IN std_logic_VECTOR(31 downto 0);
|
91 | b: IN std_logic_VECTOR(31 downto 0);
|
92 | clk: IN std_logic;
|
93 | ce: IN std_logic;
|
94 | result: OUT std_logic_VECTOR(31 downto 0));
|
95 | END COMPONENT;
|
96 | ---------------------------------------------
|
97 | COMPONENT addFP IS
|
98 | port (
|
99 | a: IN std_logic_VECTOR(31 downto 0);
|
100 | b: IN std_logic_VECTOR(31 downto 0);
|
101 | clk: IN std_logic;
|
102 | ce: IN std_logic;
|
103 | result: OUT std_logic_VECTOR(31 downto 0));
|
104 | END COMPONENT;
|
105 | --=======================================================
|
106 | --==================== Signale für afkt ==================================
|
107 |
|
108 | CONSTANT PIdiv2 :std_logic_vector(31 DOWNTO 0):=X"3FC90FDB";--1.57079632679 PI/2=+90 deg
|
109 | CONSTANT PIndiv2 :std_logic_vector(31 DOWNTO 0):=X"BFC90FDB";--1.57079632679 -PI/2=-90 deg
|
110 | CONSTANT PI :std_logic_vector(31 DOWNTO 0):=X"40490FDB";-- +3.14159265359-- PI=180 deg
|
111 | CONSTANT PIn :std_logic_vector(31 DOWNTO 0):=X"C0490FDB";-- -3.14159265359-- PI=-180 deg
|
112 | CONSTANT PIn135 :std_logic_vector(31 DOWNTO 0):=X"C016CBE4";-- -2.35619449019-- -135 deg
|
113 | CONSTANT PI135 :std_logic_vector(31 DOWNTO 0):=X"4016CBE4";-- +2.35619449019-- +135 deg
|
114 | -----------------------------------------------
|
115 | SIGNAL stateatan :integer range 0 to 15:= 0;
|
116 | --SIGNAL ceatan extern
|
117 | SIGNAL cecomp :std_logic:= '0';
|
118 | SIGNAL fYgr :std_logic_vector(0 DOWNTO 0):=(OTHERS => '0');--if Y(a)>X(b) then := '1'
|
119 | SIGNAL Yneg :std_logic:='0';-- flag Y negativ = 1
|
120 | SIGNAL Xneg :std_logic:='0';-- flag X negativ = 1
|
121 | SIGNAL Yabs :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Abs Input Yinp
|
122 | SIGNAL Xabs :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Abs Input Xinp
|
123 | SIGNAL adiv :std_logic_VECTOR(31 downto 0):=X"00000000";
|
124 | SIGNAL bdiv :std_logic_VECTOR(31 downto 0):=X"00000000";
|
125 | SIGNAL ainp :std_logic_VECTOR(31 downto 0):=X"00000000";-- inputs für Addition/subtraktion
|
126 | SIGNAL binp :std_logic_VECTOR(31 downto 0):=X"00000000";--inputs für Addition/subtraktion
|
127 | SIGNAL cediv :std_logic:= '0';
|
128 | signal resdiv :std_logic_VECTOR(31 downto 0):=X"00000000";-- resutat a/b
|
129 | SIGNAL ce1 :std_logic:='0';-- Start resdiv^2
|
130 | --
|
131 | SIGNAL ain :std_logic_VECTOR(31 downto 0):=X"00000000";-- resultat resdiv^2= input afkt
|
132 | SIGNAL ce2 :std_logic:= '0'; -- start afkt
|
133 | SIGNAL aou :std_logic_VECTOR(31 downto 0):=X"00000000";--resultaat afkt(resdiv^2)
|
134 | ---
|
135 | SIGNAL ce3 :std_logic:= '0';-- start atang = aou* ainp
|
136 | SIGNAL atang :std_logic_VECTOR(31 downto 0):=X"00000000";--resultat atang[-1,1]
|
137 | -----------
|
138 | SIGNAL ceadd :std_logic:= '0'; -- start add
|
139 | SIGNAL cesub :std_logic:= '0'; -- start sub
|
140 | SIGNAL atanFPa :std_logic_VECTOR(31 downto 0):=X"00000000";-- resultat nach addition
|
141 | SIGNAL atanFPs :std_logic_VECTOR(31 downto 0):=X"00000000";-- resultat nach substraction
|
142 |
|
143 |
|
144 | -- atanFP resultat ----
|
145 | --==================================================================
|
146 | BEGIN
|
147 | --------------------------------------------------------------
|
148 | patan :PROCESS (clk)
|
149 | VARIABLE cntrclk : INTEGER RANGE 0 TO 127:= 0;
|
150 | --variable state :INTEGER RANGE 0 TO 15:= 0;
|
151 | variable sign :std_logic_vector(1 DOWNTO 0):= "00";--Yneg(1),Xneg(0)
|
152 | BEGIN
|
153 | IF rising_edge(clk) THEN
|
154 | IF nrst = '0' THEN
|
155 | stateatan <= 0;
|
156 | cntrclk := 0;
|
157 | cecomp <= '0';
|
158 | sign := "00";
|
159 | --(OTHERS => '0');
|
160 | ELSE
|
161 | CASE stateatan IS
|
162 | WHEN 0 =>
|
163 | IF ceatan = '1' THEN
|
164 | IF (Yinp = X"00000000") AND (Xinp = X"00000000") THEN
|
165 | atanFP <= X"00000000";
|
166 | stateatan <= 0;-- ungültige wert
|
167 | ELSE
|
168 | stateatan <= 1;
|
169 | END IF;
|
170 | ELSE
|
171 | stateatan <= 0;
|
172 | END IF;
|
173 | WHEN 1 => ---testen Yinp
|
174 | IF Yinp(31) = '1' THEN -- if negativ
|
175 | Yabs <= Yinp AND X"7FFFFFFF";
|
176 | sign(1) := '1';-- Y negativ
|
177 | ELSE
|
178 | Yabs <= Yinp;
|
179 | sign(1) := '0';-- Y positiv
|
180 | END IF;
|
181 | IF Xinp(31) = '1' THEN -- if negativ
|
182 | Xabs <= Xinp AND X"7FFFFFFF";
|
183 | sign(0) := '1'; -- X negativ
|
184 | ELSE
|
185 | Xabs <= Xinp;
|
186 | sign(0) := '0'; -- X positi
|
187 | END IF;
|
188 | cecomp <= '1';-- start für comp Xabs >= Yabs
|
189 | stateatan <= 2;
|
190 | WHEN 2 =>
|
191 | cecomp <= '0';-- reset
|
192 | stateatan <= 3;
|
193 | WHEN 3 => --cmpgr if (a)Yabs > (b)Xabs th
|
194 | -- oktanten 2,3,6, 7
|
195 | IF fYgr = "0001" THEN -- if Yabs > Xabs :
|
196 | adiv <= Xabs;-- Inputs vertauschen
|
197 | bdiv <= Yabs;
|
198 | ELSE -- Yabs <= Xabs,Oktant 1,4,5,8
|
199 | adiv <= Yabs;
|
200 | bdiv <= Xabs;
|
201 | END IF;
|
202 | cntrclk := 1;
|
203 | cediv <= '1';-- div starten
|
204 | stateatan <= 4;
|
205 | WHEN 4 => -- div ausführen
|
206 | IF cntrclk > 0 THEN
|
207 | cntrclk := cntrclk -1;
|
208 | cediv <= '0';-- reset
|
209 | stateatan <= 4;
|
210 | ELSE
|
211 | ce1 <= '1';-- star für x^2
|
212 | stateatan <= 5;
|
213 | END IF;
|
214 | WHEN 5 => -- sq(x) cinpsq ausführen
|
215 | ce1 <= '0';
|
216 | ce2 <= '1';-- start für afkt
|
217 | cntrclk := 11;
|
218 | stateatan <= 6;
|
219 | WHEN 6 => ---- afkt ausführen
|
220 | IF cntrclk = 0 THEN
|
221 | ce3 <= '1';-- aou * resdiv starten
|
222 | stateatan <= 7;--afkt fertig
|
223 | ELSE
|
224 | ce2 <= '0'; --reset
|
225 | cntrclk := cntrclk -1;
|
226 | stateatan <= 6;
|
227 | END IF;
|
228 | WHEN 7 => --aou * ainp=resdiv ausführen, atang[0,1] fertig
|
229 | ce3 <= '0';-- reset
|
230 | stateatan <= 8;
|
231 | WHEN 8 =>
|
232 | binp <= atang;-- resultat arctang[0,1]
|
233 | IF fYgr = "0001" THEN -- if Yabs > Xabs :,Okt=2
|
234 | IF sign = "00" THEN -- oktant 2: 90grd - resdiv
|
235 | ainp <= PIdiv2;--start 90gr - resdiv
|
236 | stateatan <= 12;-- zu sub
|
237 | ELSIF sign = "01" THEN -- oktant 3:90grd + resdiv
|
238 | ainp <= PIdiv2;--
|
239 | stateatan <= 9;-- zu add
|
240 | -------
|
241 | ELSIF sign = "10" THEN -- oktant 7:270Grd + resdiv
|
242 | ainp <= PIndiv2;--start -90grd + resdiv
|
243 | stateatan <= 9;
|
244 | ELSE ---------sign = "11" THEN -- oktant6
|
245 | ainp <= PIndiv2;--start -90grd - resdiv
|
246 | stateatan <= 12;
|
247 | END IF;
|
248 | ELSE -- Yabs >= Xabs,
|
249 | IF sign = "00" THEN -- oktant 1
|
250 | ainp <= X"00000000";-- ohne aenderung
|
251 | stateatan <= 9;
|
252 | ELSIF sign = "01" THEN --oktant 4: 180grd - resdiv
|
253 | ainp <= PI;--start 180grd - resdiv
|
254 | stateatan <= 12;
|
255 | -------
|
256 | ELSIF sign = "10" THEN -- oktant 8
|
257 | ainp <= X"00000000";----start 0 grd - resdiv
|
258 | stateatan <= 12;
|
259 | ELSE ----- sign = "11" THEN -- oktant5
|
260 | ainp <= PIn;----start -180grd + resdiv
|
261 | stateatan <= 9;
|
262 | END IF;
|
263 | END IF;
|
264 | --------------------------------
|
265 | WHEN 9 => -- adition ausführen
|
266 | ceadd <= '1';-- start add
|
267 | --atanFP <= atanFPa;-- resultat speichern
|
268 | stateatan <= 10;--warten auf nächste Start
|
269 | WHEN 10 =>
|
270 | ceadd <= '0';-- reset
|
271 | --atanFP <= atanFPa;-- resultat speichern
|
272 | stateatan <= 11;--warten auf nächste Start
|
273 | WHEN 11 =>
|
274 | atanFP <= atanFPa;-- resultat speichern
|
275 | stateatan <= 0;
|
276 | ------------------------------
|
277 | WHEN 12 => -- subtraktion ausführen
|
278 | cesub <= '1';-- start sub
|
279 | --atanFP <= atanFPs;-- resultat speichern
|
280 | stateatan <= 13; --warten auf nächste Start
|
281 | WHEN 13 =>
|
282 | cesub <= '0';-- reset
|
283 | --atanFP <= atanFPs;-- resultat speichern
|
284 | stateatan <= 14; --
|
285 | WHEN 14 =>
|
286 | atanFP <= atanFPs;-- resultat speichern
|
287 | stateatan <= 0; --warten auf nächste Start
|
288 | ---------------------------------
|
289 | WHEN OTHERS =>
|
290 | stateatan <= 0;
|
291 | END CASE;
|
292 | END IF; -- if nrst/else
|
293 | END IF; -- clk
|
294 | END PROCESS;--end pacos
|
295 |
|
296 | --=======Implementation==================================
|
297 | -- Werte aus cfunctg-------------------------
|
298 | --X"40b5aa96",--P0 +5.67707365457 index 0
|
299 | --X"40723f49",--P1 +3.78511273085
|
300 | --X"3e76b19e",--P2 +0.240911935532 index 2
|
301 | --X"00000000"
|
302 |
|
303 | --X"40b5aa9c",--Q0 +5.67707629595 index 0
|
304 | --X"40b5ac55",--Q1 +5.6772864448
|
305 | --X"3f800000",--Q2 +1.0 indesx 2
|
306 | --X"00000000"
|
307 |
|
308 | Cafkt: afkt
|
309 | generic map(P0=>X"40b5aa96",-- +5.67707365457 index 0
|
310 | P1=>X"40723f49",-- +3.78511273085
|
311 | P2=>X"3e76b19e",-- +0.240911935532 index 2
|
312 | Q0=>X"40b5aa9c",-- +5.67707629595 index 0
|
313 | Q1=>X"40b5ac55",-- +5.6772864448
|
314 | Q2=>X"3f800000"-- +1.0 indesx 2
|
315 | )
|
316 | port map(nrst=>nrst,clk=>clk,ceafkt=>ce2,Xinp=>ain,aout=>aou);
|
317 | --cfunctg: func_atg port map(nrst=>nrst,clk=>clk,cefkt=>ce2,Xinp=>ain,aout=>aou);-- abgeschaltet
|
318 |
|
319 | ccomp: cmpgr port map(a=>Yabs,b=>Xabs,clk=>clk,ce=>cecomp,result=>fYgr);
|
320 |
|
321 | cdiv: divFP port map(a=>adiv,b=>bdiv,clk=>clk,ce=>cediv,result=>resdiv);
|
322 |
|
323 | cinpsq: mulFP port map(a=>resdiv,b=>resdiv,clk=>clk,ce=>ce1,result=>ain);
|
324 |
|
325 | cfuncmul: mulFP port map(a=>resdiv,b=>aou,clk=>clk,ce=>ce3,result=>atang);
|
326 |
|
327 | cadd: addFP port map(a=>ainp,b=>binp,clk=>clk,ce=>ceadd,result=> atanFPa);
|
328 | csub: subFP port map(a=>ainp,b=>binp,clk=>clk,ce=>cesub,result=> atanFPs);
|
329 |
|
330 |
|
331 |
|
332 | ---------------------------------------------------
|
333 |
|
334 |
|
335 | END Behavioral;
|