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;
|