atanFP.vhd


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;