AxConv.vhd


1
----------------------------------------------------------------------------------
2
3
-- Company: 
4
-- Engineer:  A:Kurka
5
-- 
6
-- Create Date:   21.6.2021 modif:21.06.24
7
-- Design Name: AS21
8
-- Module Name:    AxConv - Behavioral, Konvertiert FP Winkel[32] in Rad 
9
-- zu  AchsInkr[24bit] anzahl Inkremente gemaäss Achsen Auflösung Resol =  C_ AxRad (konstanten)
10
----------------------------------------------------------------------------------
11
library IEEE;
12
use IEEE.STD_LOGIC_1164.ALL;
13
---use IEEE.STD_LOGIC_ARITH.ALL;
14
---use IEEE.STD_LOGIC_UNSIGNED.ALL;
15
---use IEEE.STD_LOGIC_UNSIGNED.ALL;
16
--use ieee.std_logic_signed.ALL;
17
--USE ieee.math_real.all;
18
use IEEE.numeric_std.all;
19
20
--library UNISIM;
21
--use UNISIM.VComponents.all;
22
23
entity AxConv is
24
  port (
25
    nrst    : in std_logic;
26
    clk     : in std_logic;
27
    ceConv   :  in std_logic;
28
    AFPinp  :in std_logic_vector(31 downto 0);--Input Achse in  FP
29
    Resol    :in std_logic_vector(31 downto 0);--Achsen Auflössung in Inkr/Rad :C_AxRad
30
    AchsInkr   :out std_logic_vector(31 downto 0);-- Anzahl Inkremente
31
    AXgrd    :out std_logic_vector(15 downto 0)-- Achsenwinkel In Grd.X
32
    );
33
end AxConv;
34
35
36
architecture Behavioral of AxConv is
37
38
------------------------------------------------------------
39
COMPONENT divFP IS
40
  port (
41
  a: IN std_logic_VECTOR(31 downto 0);
42
  b: IN std_logic_VECTOR(31 downto 0);
43
  clk: IN std_logic;
44
  ce: IN std_logic;
45
  result: OUT std_logic_VECTOR(31 downto 0)
46
  );
47
END COMPONENT;
48
----------------------------------------------------
49
COMPONENT mulFP IS
50
  port (
51
  a: IN std_logic_VECTOR(31 downto 0);
52
  b: IN std_logic_VECTOR(31 downto 0);
53
  clk: IN std_logic;
54
  ce: IN std_logic;
55
  result: OUT std_logic_VECTOR(31 downto 0));
56
END COMPONENT;
57
---------------------------------------------------------
58
COMPONENT FPtoInt16 IS
59
  port (
60
  a: IN std_logic_VECTOR(31 downto 0);
61
  clk: IN std_logic;
62
  ce: IN std_logic;
63
  result: OUT std_logic_VECTOR(15 downto 0)
64
  );
65
END COMPONENT;
66
----------------------------------------------------
67
COMPONENT FPtoInt32 IS  --umwandlung in 24 bit SLV
68
  port (
69
  a: IN std_logic_VECTOR(31 downto 0);
70
  clk: IN std_logic;
71
  ce: IN std_logic;
72
  result: OUT std_logic_VECTOR(31 downto 0));
73
END COMPONENT;
74
75
--===========================================================
76
----------------------------------------
77
78
CONSTANT FP3600 :std_logic_vector(31 downto 0):=X"45610000";-- FP von 3600
79
CONSTANT PI2   :std_logic_vector(31 downto 0):=X"40c90fdb";--FP von 2PI
80
-------------------------------------------------
81
SIGNAL AinkrFP    :std_logic_vector(31 downto 0):=X"00000000";-- FP-Winkel in Inkrementen
82
SIGNAL AFPMul     :std_logic_vector(31 downto 0):=X"00000000";-- AFPmul:=Afpinp * FP3600
83
SIGNAL AFPGrd    :std_logic_vector(31 downto 0):=X"00000000";-- AFPGrd:=AfPmul / 2Pi
84
-----------------------------
85
SIGNAL ceAinkr    :STD_LOGIC:= '0';-- Start für mul AFPint * Inkr/Rad
86
SIGNAL cemul    :STD_LOGIC:= '0';-- Start für sub
87
SIGNAL ceTo16    :STD_LOGIC:= '0';-- Start für FpToInt16=AxGrad
88
SIGNAL cediv    :STD_LOGIC:= '0';-- start für AFP/PI2
89
90
--==============================================================================
91
begin
92
--===========================================================
93
--AxConv(pAxConv):
94
--Rechnet Diferenz Alt-Neu  (FP) : AinkrAlt - AinpFP=> DiffFP
95
-- wenn DiffFP > 1 set: InkrAx:=1 resp. DiffFP <-1 set DekrAX:= 1
96
-- wird von ITPImpGen benützt für Achsen A0..A5
97
--================================================================
98
pAxConv: PROCESS
99
VARIABLE stateConv : INTEGER RANGE 0 TO 15:= 0;
100
101
BEGIN
102
  ----IF rising_edge(clk) THEN
103
  wait until (rising_edge(clk));
104
    IF nrst = '0' THEN
105
      stateConv := 0;
106
      ceAinkr <= '0';
107
      cemul <= '0';
108
      cediv <= '0';
109
      ceTO16 <= '0';
110
    ELSE
111
      CASE stateConv IS
112
        WHEN 0 =>
113
          IF ceConv = '1' THEN-- AFPint = Achsenwinkel in RAD FP
114
            ceAinkr <= '1'; --start AinkrFP := AFPint * C_AxRad[Inkr/Rad]
115
            stateConv := 1;
116
          ELSE
117
            stateConv := 0;
118
          END IF;
119
        WHEN 1 => --AinkrFP := AFPint * C_AxRad[Inkr/Rad] fertig
120
          ceAinkr <= '0'; --reset ce
121
          cemul <= '1'; --  Start für mulFP und FPtoInt24  
122
          stateConv := 2;
123
        WHEN 2 => -- ausführen mulFP und FPtoInt32: AchsInkr bereit  
124
          cemul <= '0';-- init
125
          cediv <= '1';-- AFPmul/PI2 starten
126
          stateConv := 3;-- 
127
        WHEN 3 => -- ausführen AFPmul/PI2
128
          cediv <= '0';-- reset
129
          ceto16 <= '1'; -- start FPToInt16: AXGrd.x
130
          stateConv := 4;
131
        WHEN 4 => -- ausführen FPToInt16  
132
          ceto16 <= '0'; --reset CE
133
          stateConv := 5;
134
        WHEN 5 =>
135
          stateConv := 0;-- und warte auf nächste durchlauf
136
        WHEN OTHERS  => 
137
          stateConv := 0;
138
      END CASE;
139
    END IF; -- if nrst/else
140
  ---END IF; -- clk
141
END PROCESS;--end pAxConv
142
143
144
--=======================================================================        
145
cmulAFp:    mulFP   port map(a=>AFPinp,b=>Resol,clk=>clk,ce=>ceAinkr,result=>AinkrFP);-- state 1
146
cmulFP:    mulFP    port map(a=>AFPinp,b=>FP3600,clk=>clk,ce=>cemul,result=>AFPmul);-- state 2
147
cFPInt32:  FPtoInt32 port map(a=>AinkrFP ,clk=>clk, ce=>cediv ,result=>AchsInkr); -- state 2,Ax inkr[24bit]  
148
cdivGRD:    divFP   port map(a=>AFPmul,b=>PI2,clk=>clk,ce=>cediv,result=>AFPGrd);-- state 3   
149
cFPInt16:  FPtoInt16 port map(a=>AFPGrd ,clk=>clk, ce=>ceTo16 ,result=>AXGrd); --state4 ,AxGrd.x[16bit] 
150
 
151
-------------------------------------------------
152
end Behavioral;