runangle.vhd


1
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: 
4
-- 
5
-- Create Date:    09:36:37 08/20/2024 
6
-- Design Name: 
7
-- Module Name:    runangle - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description: 
12
--
13
-- Dependencies: 
14
--
15
-- Revision: 
16
-- Revision 0.01 - File Created
17
-- Additional Comments: 
18
--
19
----------------------------------------------------------------------------------
20
library IEEE;
21
use IEEE.STD_LOGIC_1164.ALL;
22
use IEEE.NUMERIC_STD.ALL;
23
24
--library IEEE;
25
--use IEEE.STD_LOGIC_1164.ALL;
26
--use IEEE.STD_LOGIC_ARITH.ALL;
27
----use IEEE.STD_LOGIC_UNSIGNED.ALL;
28
--use ieee.std_logic_signed.ALL;
29
----USE ieee.math_real.all;
30
--use IEEE.numeric_std.all;
31
32
33
entity runangle is
34
  port (nrst    : in std_logic;
35
      clk     : in std_logic;
36
--      XS      :in std_logic_vector(31 downto 0);-- Startpunkt Koordinate X
37
--      YS      :in std_logic_vector(31 downto 0);-- Startpunkt Koordinate Y
38
--      ZS      :in std_logic_vector(31 downto 0);-- Startpunkt Koordinate Z
39
--      XT      :in std_logic_vector(31 downto 0);-- Koordinate X relativ (XE-XS)
40
--      YT      :in std_logic_vector(31 downto 0);-- Koordinate Y  relativ (YE-YS)
41
--      ZT      :in std_logic_vector(31 downto 0);-- Koordinate Z  relativ (ZE-ZS)
42
--      pfrq    :in std_logic_vector(23 downto 0);--Bahn-Periode in anzahl CLK 
43
--      L1      :in std_logic_vector(15 downto 0);-- länge Arm1 in mm
44
--      L2      :in std_logic_vector(15 downto 0);-- länge Arm2 in mm
45
--      L3      :in std_logic_vector(15 downto 0);-- länge Arm3 in mm
46
      ---------------------
47
--      Xlin    :in std_logic_vector(15 downto 0);-- Koord LinStz
48
--      Ylin    :in std_logic_vector(15 downto 0);-- Max.Eingabe +/-327.67
49
--      ebene    :in std_logic_vector(3 downto 0);--interpolationsebene für LinSatz
50
--      Xactiv  :in std_logic;
51
--      Yactiv  :in std_logic;
52
--      celin    :in std_logic;---start interpolation für linstz in einer ebene
53
      --------------------------------------
54
--      stopp    :in std_logic;-- stop interpolation,(stopp+) nach  Endlage
55
--      RampRun  :in std_logic;-- rampe aktiv =1
56
      strimp  :in std_logic;-- start interpolation
57
--      ce      :in std_logic;-- start interpolation von kreis oder XYZ Satz : InversTransf
58
      -----------------------------
59
--      calcok  :out std_logic:= '0';-- signalisiert alle berechnungen sind fertig
60
--      XAout    :out std_logic_vector(31 downto 0):=X"00000000";--virtuelle aktuelle koordinate
61
--      YAout    :out std_logic_vector(31 downto 0):=X"00000000";
62
--      ZAout    :out std_logic_vector(31 downto 0):=X"00000000";
63
--      ITPmod   :out std_logic_vector(2 DOWNTO 0):="000";--ITP für Status Meldung an CPU
64
--      oAXdif  :out std_logic_vector(95 downto 0):= (OTHERS => '0');--Sollwertdiff(16Bit) von  inv.Transfer und Lin
65
--      oImpLk  :out std_logic:='1';--impulse von xyz itp
66
--      enditp   :out std_logic:='0';-- ende von Kontur:=0 (enditp-)
67
--      itprun  :out std_logic:='0';-- =1:interpolator läuft,aktuelle Sollwerte in oAXinkr(6x 32bit)
68
--      testdata :out std_logic_vector(15 downto 0):= X"0000";
69
70
      
71
      ImpLk  : in std_logic -- Signal in die Port map verschoben, dass man es testen kann (sonst wird es entfernt)
72
      );
73
  
74
end runangle;
75
76
architecture Behavioral of runangle is
77
78
CONSTANT clkToFP : integer range 0 to 127 := 1;
79
CONSTANT clkTosq : integer range 0 to 127 := 1;
80
CONSTANT clkTomul : integer range 0 to 127 := 1;
81
CONSTANT clkToadd : integer range 0 to 127 := 1;
82
CONSTANT clkTosub : integer range 0 to 127 := 1;
83
CONSTANT clkTosqrt : integer range 0 to 127 := 1;
84
CONSTANT clkTodiv : integer range 0 to 127 := 2;
85
CONSTANT clkFPtoInt : integer range 0 to 127 := 1;
86
CONSTANT clkToAtan : integer range 0 to 127 := 25;
87
CONSTANT clkToAcos : integer range 0 to 127 := 25;
88
CONSTANT clkToCos : integer range 0 to 127 := 25;
89
CONSTANT clkAtan : integer range 0 to 127 := 30;
90
CONSTANT clkAtan32 : integer range 0 to 127 := 11;
91
CONSTANT clkdiv32 : integer range 0 to 127 := 32;
92
93
CONSTANT clkTosin  : integer range 0 to 127 := 1;
94
CONSTANT clkToMuli  : integer range 0 to 127 := 2;
95
CONSTANT C2     :std_logic_vector(31 DOWNTO 0):=X"40000000";-- zahl 2 in FP format 32bit
96
CONSTANT C1     :std_logic_vector(31 DOWNTO 0):=X"3F800000";-- zahl 1 in FP format 32bit
97
CONSTANT C0     :std_logic_vector(31 DOWNTO 0):=X"00000000";-- zahl 0 in FP format 32bit
98
CONSTANT PIdiv2   :std_logic_vector(31 DOWNTO 0):=X"3FC90FDB";-- +1.57079632679 PI/2 in FP Format
99
CONSTANT PIndiv2   :std_logic_vector(31 DOWNTO 0):=X"BFC90FDB";-- -1.57079632679 PI/2 in FP Format
100
CONSTANT PI      :std_logic_vector(31 DOWNTO 0):=X"40490FDB";-- 3.14159265359 PI in FP Format
101
102
-------
103
CONSTANT C132   :std_logic_vector(31 DOWNTO 0):=X"20000000";--zahl 1 in format 1Q32 bit
104
CONSTANT C126   :std_logic_vector(25 DOWNTO 0):="01" & X"000000";--zahl 1 in format 1Q26 bit
105
CONSTANT C026   :std_logic_vector(25 DOWNTO 0):="00" & X"000000";-- zahl 0 in FP format 26bit
106
CONSTANT Pihalf :std_logic_vector(25 DOWNTO 0):="001" & "10010010000111111011000";--Pi Half in 2Q26
107
108
SIGNAL ctrPLk :Integer range 0 to 33554431;-- dekr. Counter  für Imp. Periode
109
--SIGNAL ImpLk  :std_logic;-- inkrement virtuelle Lk Impuls von XYZ ITP (invers Trans)
110
SIGNAL grPI2  :std_logic;
111
112
-----RUNANGLE Berechnung : a0 := arctan(Ya/Xa) und aXYT:=arctan(YT/XT) Berechnung-------------------------------                            
113
SIGNAL ceXYZFP   :std_logic;
114
115
-----------------------state 0---------------------
116
SIGNAL FXYZaOK    :std_logic;--signalisiert wenn FXYZa bereit
117
SIGNAL suPIAT  :std_logic_vector(31 downto 0);
118
SIGNAL adPIAT  :std_logic_vector(31 downto 0);
119
----------------- state 2----------------------------------
120
SIGNAL cePI2   :std_logic;-- start für sPIAT := PI/2 - PIATabs für sin AT 
121
SIGNAL PIAT    :std_logic_vector(31 downto 0);
122
---------------- state 3 ----------------------------------
123
SIGNAL cetgFP     :std_logic;
124
-----------------State 9 ---------------------------------
125
SIGNAL cemul9   :std_logic;
126
-----------------State 10 -----------------------------------
127
SIGNAL cemul10   :std_logic;
128
-----------------State 11---------------------------
129
SIGNAL cesubW   :std_logic:='0';
130
SIGNAL aFXw  :std_logic_vector(31 downto 0);--
131
SIGNAL sFXw  :std_logic_vector(31 downto 0);--
132
SIGNAL FXw  :std_logic_vector(31 downto 0);--
133
---------------- State 12------------------------------
134
SIGNAL cemul12   :std_logic;
135
---------------state 13-----------------------------------
136
SIGNAL ceaddXYw   :std_logic;
137
---------------- State 14 ---------------------------------
138
SIGNAL cesqrtLw   :std_logic;
139
SIGNAL cemAZA3   :std_logic;
140
SIGNAL DivPIdiv  :std_logic_vector(31 downto 0);--
141
------------------state 15----------------------------
142
SIGNAL cedAZA3   :std_logic; 
143
------------------state 16 -----------------------------------
144
SIGNAL cedivPIdiv   :std_logic;
145
SIGNAL ceA4FP   :std_logic;   
146
----------------- state 17 -----------------------------------
147
SIGNAL ceAZmul   :std_logic;
148
----------------- state 18 --------------------------------
149
SIGNAL absdivPIdiv  :std_logic_vector(31 downto 0);--
150
----------------- state 19 --------------------------------
151
SIGNAL cesub1min   :std_logic;
152
----------------- state 20 --------------------------------
153
SIGNAL ceA3FP   :std_logic;
154
155
----------------state 22-- nur für test ----------------- 
156
SIGNAL ceXYZw :std_logic;
157
158
SIGNAL ceP1 :std_logic;--start sq für P1
159
SIGNAL cesqL :std_logic;
160
161
SIGNAL ceadd1 :std_logic;
162
SIGNAL cesub1 :std_logic;
163
164
SIGNAL cediv1  :std_logic;
165
---------------------------
166
SIGNAL ceacosFP   :std_logic;-- Start arccosFP
167
SIGNAL ceA1FP  :std_logic;
168
SIGNAL cesubA1  :std_logic;
169
SIGNAL cecosFP  :std_logic;
170
171
------ RUNANGLE vorher Calc P1 blatt1 fertig, Blatt2 anfang
172
SIGNAL ceZW12    :std_logic;
173
SIGNAL ceatanZW    :std_logic;
174
SIGNAL cesubA2    :std_logic;
175
176
---------------------
177
SIGNAL ceZ1W1  :std_logic;
178
179
180
signal ctrclk : integer range 0 to 127;
181
SIGNAL stateangle :integer range 0 to 63;
182
signal next_stateangle : integer range 0 to 63;
183
184
begin
185
runangle:PROCESS
186
187
BEGIN
188
  wait until (rising_edge(clk));
189
  
190
    IF nrst = '0' THEN
191
      stateangle <= 0;
192
      ctrclk <= 0;
193
      FXYZaOK <= '0';
194
      ceXYZFP <= '0'; cetgFP<='0'; cemul9<='0'; cemul10<='0';
195
      cesubW <='0'; cePI2 <='0';
196
      cemAZA3 <= '0';cedAZA3 <= '0';cedivPIdiv<='0'; ceAZmul<= '0';
197
      cesub1min <= '0';ceA3FP<='0';
198
      ceA4FP <='0'; cetgFP <= '0';
199
      ceP1 <= '0';
200
      cesqL <= '0'; ceadd1 <= '0'; cesub1<= '0';
201
      cediv1 <= '0'; ceacosFP <= '0'; ceA1FP <='0';
202
      cecosFP <= '0'; ceZ1W1 <= '0'; cesubA1 <= '0';
203
--      startON := '0';
204
    ELSE
205
      CASE stateangle IS
206
        WHEN 0 =>
207
          IF (ImpLk = '0') THEN  
208
            ceXYZFP <= '1';--Start für Xa,Ya,Zz=>FP, und Pi/2-AZFP,Pi/2 +/- ATFP
209
            ctrclk <= clkToFP;
210
            stateangle <= 63;
211
            next_stateangle <= 1;
212
          ELSE
213
            FXYZaOK <= '0'; --reset          
214
          END IF;
215
          
216
        WHEN 1 => -- ausführen Xa,Ya,Zz=>FP und Pi/2-AZFP,Pi/2 +/- ATFP
217
          ceXYZFP <= '0';--reset CE
218
--          StartON := '1';
219
          stateangle <= 2;
220
          
221
        WHEN 2 =>  -- zwischen state notwendig****
222
          IF grPI2 = '1' THEN -- wenn AT > PI/2 dann  sub PI/2 sonst ADD
223
              PIAT <= suPIAT;
224
          ELSE 
225
            PIAT <= adPIAT;
226
          END IF;
227
          stateangle <= 3;
228
          
229
        WHEN 3 =>  -- zwischen state notwendig ****
230
           cePI2 <= '1';
231
           ctrclk <= clkTosub;
232
           stateangle <= 63;
233
           next_stateangle <= 4;
234
           
235
        WHEN 4 => --ausführen PIAZ :=PI/2 - PIAT
236
          cePI2 <= '0';-- reset
237
          ctrclk  <= 35;--clk Atan für durchlauf  ******  
238
          ceTgFP <= '1'; --arcTang und cos starten
239
          stateangle <= 63;
240
          next_stateangle <= 5;
241
                    
242
        WHEN 5 => --Ausführen A0FP:=atan(Ya/Xa),und Cos(4 bml),  A=FP fertig*****
243
          ceTgFP <= '0'; --Reset ArcTang start Impuls
244
          --tanYX , ATFP,AZFP fertig
245
          cemul9 <= '1';-- start sinAZ* sinAT, sinAZ* cosAT
246
          ctrclk <= clkTomul;
247
          stateangle <= 63;
248
          next_stateangle <= 9;
249
                    
250
        WHEN 9 => -- ausführen; sinAZ* sinAT, sinAZ* cosAT
251
          cemul9 <= '0';--reset
252
          ctrclk <= clkTomul;
253
          cemul10 <= '1'; --start sAZAT* FL3, cAZAT* FL3
254
          stateangle <= 63;
255
          next_stateangle <= 10;
256
                    
257
        WHEN 10 => --ausführen  sAZAT* FL3, cAZAT* FL3
258
          cemul10 <= '0';-- reset
259
          ctrclk <= clkTosub;
260
          ceSubw <= '1'; -- Start für sub/add FXa -/+ sAZAT3 usw
261
          stateangle <= 63;
262
          next_stateangle <= 11;
263
            
264
        WHEN 11 =>  -- ausführen sub/add FXa -/+ sAZAT3.. = FYw,FZw fertig
265
          ceSubw <= '0';-- reset
266
          stateangle <= 12;
267
                    
268
        WHEN 12 =>-- für test 
269
          stateangle <= 13;
270
            
271
        WHEN 13 => -- zwischen state notwendig ***
272
          IF grPI2 = '1' THEN
273
            FXw <= aFXw;
274
          ELSE 
275
            FXw <= sFXw;
276
          END IF;
277
          ctrclk <= clkTosq;
278
          cemul12 <= '1'; --Start für sqXw:=sq(FXw),sqYw:=sq(FYw) und ATPI:= ATFP-PI/2
279
          stateangle <= 63; ---FXW fertig Berechnet 
280
          next_stateangle <= 15;
281
            
282
        ----------------state reserve----------------------------
283
        WHEN 15 =>  ---  Ausführen Fxw^2,FYw^2
284
          cemul12 <= '0';-- reset
285
          stateangle <= 16;
286
                      
287
        WHEN 16 =>
288
          ceXYZw <= '1';---für test ***** XYZ W ***********************
289
          stateangle <= 17;  
290
            
291
            -----Blatt6:csqXw,csqYw, Blatt5: csubAwAt-- gestartet mit cemul12 ----------------            
292
        WHEN 17 =>  -- ausführen sqXw:=sq(FXw),sqYw:=sq(FYw)  
293
          ctrclk  <= 23;-- 22 clk für atan
294
          ceXYZw <= '0'; -- reset
295
          ceaddXYw <= '1'; --start fürAwFP:=atan(FYw/FXw) und sqXYW:=sqXw+SqYw,subPIDIV0subAtAW-pIDIV0
296
          stateangle <= 63;
297
          next_stateangle <= 18;
298
            
299
        -----Blatt6: catgAw (22clk),caddXYw, Blatt5:csubPidiv--- gestartet mit ceaddXYw---------
300
        WHEN 18 =>-- ausführen AwFP:=atan(FYw/FXw) und  sqXYW:=sqXw+ SqYw,subPidiv=subAtAw-PIdiv2
301
          ceaddXYw <= '0'; --reset 
302
          cesqrtLw <= '1'; --start LwFP:=sqrt(sqXYw) und subPIdiv= subATAW-pidIV2
303
          ctrclk  <= clkTosq;
304
          stateangle <= 63;
305
          next_stateangle <= 19;
306
                      
307
        ------Blatt6:csqrtLW, Blatt5 :cdivPIdiv2-- gestartet mit cesqrtLW ---------
308
        WHEN 19 => --ausführen LwFP:= sqrt(sqXYw),LWFP fertig, subPidiv=subAtAw-PIdiv2
309
          cesqrtLw <= '0';-- reset
310
          cemAzA3 <= '1'; --start AtFp-AwFp
311
          absDivPIdiv <= DivPIdiv;--absDivPiDiv vorläaufig setzen
312
          ctrclk <= clkTosub;
313
          stateangle <= 63;
314
          next_stateangle <= 22;
315
                    
316
        ----reserve state ----------------
317
        ----- Blatt5:csqZ2,csqW2,cmuAZFP ---- gestartet mit cemAzA3 ----------------
318
         WHEN 22 =>  --- ausführen sq(FZw),sq(LWFP), mul(AZFP,DivPIdiv)------
319
          cemAZA3 <=  '0'; --reset
320
          cedAZA3 <= '1';--start subAtAw-PIdiv2
321
          ctrclk <= clkTosub;
322
          stateangle <= 63;
323
          next_stateangle <= 23;          
324
          
325
        ---- Blatt 5:caddWZ, csub1min--- gestartet mit cedAZA3 ---------------
326
        WHEN 23 =>  --- ausführen sqaddWZ=sqZ2 + sqW2,subPIdiv =
327
          cedAZA3 <= '0';-- reset
328
          cedivPIdiv <= '1';
329
          ceA4FP <= '1'; -- start sqrt(sqaddWZ), atan A12,
330
          ctrclk  <= clkToAtan;--clk Atan
331
          stateangle <= 63;
332
          next_stateangle <= 24;
333
                    
334
        --- Blatt5:catanA12,sqrtWZ,cmulAZFP -- gestartet mit ceA4FP -------
335
        WHEN 24 => --ausführen atan(FZW,LWFP),divFp,vsqrt(sqaddWZ), mul(sub1min,AZFP)
336
          ceA4FP <= '0'; --reset
337
          cedivPIdiv <= '0';
338
          absdivPIdiv <= divPIdiv;-- vorläufig
339
          ceAZmul <= '1';
340
          ceP1 <= '1'; -- START intToFP für  L1,L2 => FL1,FL2
341
          stateangle <= 25;
342
                      
343
        WHEN 25 =>
344
          IF absDivPidiv(31) = '1' THEN
345
            absDivPidiv(31) <= '0';-- Abs von DivPiDiv
346
          END IF;
347
          ceP1 <= '0';-- FL1,FL2 fertig
348
          ceAZmul <= '0';-- a4FP fertig
349
          ctrclk <= clkTosub;
350
          cesub1min <= '1';
351
          stateangle <= 63;
352
          next_stateangle <= 26;
353
          
354
        WHEN 26 =>-- sub1min := 1 - absdivPIdiv
355
          cesub1min <= '0';
356
          ceA3FP <= '1';-- startsub1min* AZFP => A3FP 
357
          cesqL <= '1';-- start für FL11^2,Fl2^2,FL12^2
358
          ctrclk <= clkTomul;
359
          stateangle <= 63;
360
          next_stateangle <= 27;
361
                    
362
         -- Ab hier Funktionen aus calcP1---------------------------------------
363
        WHEN 27 => -- A3FP :=sub1min * AZFP, a3FP fertig,FL11^2,Fl2^2,FL12^2 
364
          cesqL <= '0';--FL11^2,Fl2^2,FL12^2=> SqL1,sqL12,sqL2  fertig
365
          ceA3FP <= '0';--a3FP fertig
366
          IF strImp = '0' THEN
367
--            StartON := '0';
368
          END IF;
369
          ceadd1<= '1'; -- startsqL1+sqL12,Fl12*FL1
370
          ctrclk <= clkTomul;
371
          stateangle <= 63;
372
          next_stateangle <= 28;
373
                    
374
        WHEN 28 => -- ausführen  L1+sqL12,Fl12*FL1  
375
          ceadd1<= '0';--L1+sqL12,Fl12*FL1  fertig
376
          cesub1 <= '1'; -- start für: sqadd1-sqL2, mul12 * 2
377
          ctrclk <= clkTomul;
378
          stateangle <= 63;
379
          next_stateangle <= 29;
380
                    
381
        WHEN 29 => -- ausführen: sqadd1-sqL2, mul12 * 2
382
          cesub1 <= '0';--sqadd1-sqL2, mul12 * 2 fertig
383
          cediv1 <= '1'; -- start sqsub1/ mulres1 => ax
384
          ctrclk <= clkToDiv;
385
          stateangle <= 63;
386
          next_stateangle <= 30;
387
          
388
        WHEN 30 =>
389
          cediv1 <= '0';--sqsub1/ mulres1 => ax fertig
390
          ceacosFP <= '1'; -- start für atang( Ax)
391
          ctrclk <= clkTOacos;
392
          stateangle <= 63;
393
          next_stateangle <= 31;  
394
          
395
        WHEN 31 =>    
396
          ceacosFP <= '0';--atang( Ax) fertig
397
          ceA1FP <= '1'; -- start für acosAx + A12FP
398
          ctrclk <= clkTOadd;
399
          stateangle <= 63;
400
          next_stateangle <= 32;          
401
          
402
        WHEN 32 =>    
403
          ceA1FP <= '0';--acosAx + A12FP => A+FP fertig ************
404
          cesubA1 <= '1'; --start für PI/2 - A1FP
405
          ctrclk <= clkTOsub;
406
          stateangle <= 63;
407
          next_stateangle <= 33;  
408
          
409
        WHEN 33 =>      
410
          cesubA1 <= '0';--PI/2 - A1FP => A1SFP fertig
411
          cecosFP <= '1'; --Start  für cos(a1FP) & cosFP(a1SFP)
412
          ctrclk <= clkTOcos;
413
          stateangle <= 63;
414
          next_stateangle <= 34;  
415
          
416
        WHEN 34 =>    
417
          cecosFP <= '0';--cos(a1FP) & cosFP(a1SFP) =>cosA1FP,sinA1FP fertig
418
          ceZ1W1 <= '1'; --start für sinA1FP*FL1, cosA1FP * FL1
419
          ctrclk <= clkTOmul;
420
          stateangle <= 63;
421
          next_stateangle <= 35;
422
          
423
        WHEN 35 =>    
424
          ceZ1W1 <= '0';--sinA1FP*FL1=> FZ1,cosA1FP * FL1=>FW1  fertig ******
425
          cezw12 <= '1'; -- start für FZw-Fz1 & LwFP-FW1
426
          ctrclk <= clkTOsub;
427
          stateangle <= 63;
428
          next_stateangle <= 36;
429
          
430
        WHEN 36 =>    
431
          cezw12 <= '0';--FZw-Fz1=Z2Z1 & LwFP-FW1=W"W1 fertig
432
          ceatanZW <= '1';-- start für atan
433
          ctrclk <= clkTOatan;
434
          stateangle <= 63;
435
          next_stateangle <= 37;
436
          
437
        WHEN 37 =>
438
          ceatanZW <= '0';-- AtanZW fertig
439
          cesubA2 <= '1'; -- start für atanZw- a1FP
440
          ctrclk <= clkTOsub;
441
          stateangle <= 63;
442
          next_stateangle <= 38;
443
          
444
        WHEN 38 =>
445
          cesubA2 <= '0';-- A2FP fertig ********************
446
          FXYZaOK <= '1';--RUNANGLE  bereit
447
          stateangle <= 0;-- alle Achsen fertig
448
          --Berechnung fertg,wartn auf nächste Start
449
                    
450
        when 63 =>
451
          if(ctrclk > 0) then
452
            ctrclk <= ctrclk - 1;
453
          else
454
            stateangle <= next_stateangle;
455
          end if;
456
          
457
        WHEN OTHERS  => stateangle <= 0;
458
      END CASE;
459
    END IF;-- nrst if/else
460
461
END PROCESS;-- end runangle
462
463
end Behavioral;