afkt.vhd


1
-- test 2, ISE 14.7 
2
---A.Kurka, 13.05.21, 
3
--afkt mit neue Formel, mit 10 clk und 5 componenten
4
--    P(X) = P0 + X*(P1 + X*P2), ausgewertet von innen nach außen
5
--    Q(X) = Q0 + X*(Q1 + X*Q2), ausgewertet von innen nach außen
6
--    a(X) = P(X) / Q(X)
7
--========================================================== 
8
library IEEE;
9
use IEEE.STD_LOGIC_1164.ALL;
10
use IEEE.STD_LOGIC_ARITH.ALL;
11
use IEEE.STD_LOGIC_UNSIGNED.ALL;
12
13
--X"3f7ffffd",--P0  +0.99999984852024669   index 0
14
--X"be8c8cb6",--P1  -0.27451104135987186
15
--X"00000000",--P2   +0.0              index 2
16
--X"00000000"             
17
----------------------------------
18
--X"3f800000",--Q0  +1.0               index 0
19
--X"beb73881",--Q1  -0.35785296234245088
20
--X"3c36a182",--Q2  +0.011146905255803363   indesx 2
21
--X"00000000"
22
23
entity afkt is
24
  generic(  P0:std_logic_vector(31 downto 0):=X"00000000";
25
        P1:std_logic_vector(31 downto 0):=X"00000000";
26
        P2:std_logic_vector(31 downto 0):=X"00000000";
27
        Q0:std_logic_vector(31 downto 0):=X"00000000";
28
        Q1:std_logic_vector(31 downto 0):=X"00000000";
29
        Q2:std_logic_vector(31 downto 0):=X"00000000"
30
        );    
31
  port(  nrst  : in std_logic;
32
      clk    : in std_logic;
33
      ceafkt  : in std_logic; -- startimpuls afkt
34
      Xinp  : in std_logic_vector(31 downto 0); -- Input in [0, 0.5] in FP-Format
35
      aout  : OUT std_logic_vector(31 downto 0) -- Output in [1, 1.047197+] in FP-Format, 1.047197=2*asin(0.5)
36
      );
37
end afkt;
38
39
architecture Behavioral of afkt is
40
----------------------------------------------------
41
COMPONENT mulFP IS
42
  port (
43
  a: IN std_logic_VECTOR(31 downto 0);
44
  b: IN std_logic_VECTOR(31 downto 0);
45
  clk: IN std_logic;
46
  ce: IN std_logic;
47
  result: OUT std_logic_VECTOR(31 downto 0));
48
END COMPONENT;
49
---------------------------------------------
50
COMPONENT addFP IS
51
  port (
52
  a: IN std_logic_VECTOR(31 downto 0);
53
  b: IN std_logic_VECTOR(31 downto 0);
54
  clk: IN std_logic;
55
  ce: IN std_logic;
56
  result: OUT std_logic_VECTOR(31 downto 0));
57
END COMPONENT;
58
------------------------------------------------------------
59
COMPONENT divFP IS
60
  port (
61
  a: IN std_logic_VECTOR(31 downto 0);
62
  b: IN std_logic_VECTOR(31 downto 0);
63
  clk: IN std_logic;
64
  ce: IN std_logic;
65
  result: OUT std_logic_VECTOR(31 downto 0)
66
  );
67
END COMPONENT;
68
-----------------------------------------------------
69
TYPE T_PQTab IS ARRAY(0 TO 3) OF std_logic_vector(31 DOWNTO 0); -- Koeff Tabelle für Polynom mit Grad <= 3.
70
--==========================================================================
71
CONSTANT Cnan : std_logic_vector(31 DOWNTO 0) := X"FFC00000"; -- silent NaN (Not-a-Number) in FP IEEE single (32bit)
72
CONSTANT C0  :std_logic_vector(31 DOWNTO 0) := X"FFC00000";--Null im FP Format
73
------------------------------------------------------------------------
74
-- Koeffizienten-Tabellen für P / Q, MiniMax Approximation, X in [0, 1/2].
75
-- a(x) = p(x) / q(x) = asin(sqrt(x/2)) / sqrt(x/2)
76
-- p(x) = 2.2395545700203E+01 + x * (-9.2247557732604 + x * 4.9573581589364E-01)
77
-- q(x) = 2.2395545641439E+01 + x * (-1.1091046068928E+01 + x)
78
-- |rel. Fehler| < 1.63e-9 (5e-7 mit IEEE single).
79
--
80
--CONSTANT PTab : T_PQTab :=
81
--(
82
--  X"41b32a14", -- P0  +2.2395545700203E+01
83
--  X"c113989a", -- P1  -9.2247557732604
84
--  X"3efdd116", -- P2  +4.9573581589364E-01
85
--  X"00000000"  -- unused
86
--);
87
--CONSTANT QTab : T_PQTab :=
88
--(
89
--  X"41b32a14", -- Q0  +2.2395545641439E+01
90
--  X"c13174ed", -- Q1  -1.1091046068928E+01
91
--  X"3f800000", -- Q2  +1.0
92
--  X"00000000"  -- unused
93
--);
94
-- koeffizienten Tabellen für P , MinMax Approximation
95
CONSTANT PTab :T_PQTab:= -- alle werte in FP
96
(
97
P0,------------------X"3f7ffffd",--P0  +0.99999984852024669   index 0
98
P1,-------------------X"be8c8cb6",--P1  -0.27451104135987186
99
P2,--------------------X"00000000",--P2   +0.0              index 2
100
X"00000000"             
101
);
102
--------------------------------
103
CONSTANT QTab :T_PQTab:= -- alle werte in FP
104
(
105
Q0,--------------X"3f800000",--Q0  +1.0               index 0
106
Q1,----------X"beb73881",--Q1  -0.35785296234245088
107
Q2,-----------X"3c36a182",--Q2  +0.011146905255803363   indesx 2
108
X"00000000"
109
);  
110
--==================== Signale für afkt ==================================
111
SIGNAL stateafkt  :integer range 0 to 7:= 0;
112
--SIGNAL ceafkt   :std_logic:='0';-- Startimpuls afkt, extern
113
SIGNAL ce1      :std_logic:='0';-- Start Pmul = Xinp*Pinp;   Qmul = Xinp*Qinp
114
SIGNAL ce2      :std_logic:='0';-- Start Padd = Pmul+PKoeff; Qadd = Qmul+QKoeff
115
SIGNAL ce3      :std_logic:='0';-- Start aout = Pplus/Qplus
116
SIGNAL ce4      :std_logic:='0';-- Start aout = Padd/Qadd
117
SIGNAL RDYdiv    :std_logic:='0';-- Div Result Ready 
118
SIGNAL Pinp      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- 2. Input cPmul
119
SIGNAL Qinp      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- 2. input cQmul
120
121
SIGNAL Pmul      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPmul
122
SIGNAL Qmul      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cQmul
123
SIGNAL Pplus    :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPmul
124
SIGNAL Qplus    :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cQmul
125
SIGNAL Pa      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPadd
126
SIGNAL Qa      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPadd
127
SIGNAL Padd      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPadd, Ergebnis Auswertung P()
128
SIGNAL Qadd      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cQadd, Ergebnis Auswertung Q()
129
SIGNAL PKoeff    :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Koeff von P()
130
SIGNAL QKoeff    :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Koeff von Q()
131
--================================================================
132
begin
133
--=========== a(x) ==============================================
134
-- a(X) = (P0 + P1*X + P2*X^2) / (Q0 + Q1*X + Q2*X^2)
135
-- Berechnungsformel:
136
--    P(X) = P0 + X*(P1 + X*P2), ausgewertet von innen nach außen
137
--    Q(X) = Q0 + X*(Q1 + X*Q2), ausgewertet von innen nach außen
138
--    a(X) = P(X) / Q(X)
139
140
--************************************************************************ 
141
pafkt:PROCESS(clk) -- Process für a(Xinp), vorläufig 8(?) clk.
142
143
-- als Index in PTab und QTab.
144
VARIABLE TabIdx : INTEGER RANGE 0 TO 3 := 0;
145
VARIABLE count :INTEGER RANGE 0 TO 7:= 0;
146
BEGIN
147
  IF rising_edge(clk) THEN  
148
    IF nrst = '0' THEN 
149
      TabIdx := 0; -- Init Inx Pointer
150
      PKoeff <= C0; 
151
      QKoeff <= C0; 
152
      Pinp   <= C0;
153
      Qinp   <= C0; 
154
      ce1 <= '0';
155
      ce2 <= '0';
156
      ce4 <= '0';
157
      stateafkt <= 0;
158
    ELSE
159
      CASE stateafkt IS
160
      WHEN 0 => -- Start afkt
161
        IF ceafkt = '1' THEN
162
          TabIdx := 2; -- Init Index in Tabellen (1 = max. Polynomgrad - 1)--****************.
163
          Pinp <= PTab(2); -- Init Pinp = PTab(2), (2 = max. Polynomgrad)
164
          Qinp <= QTab(2); -- Init Qinp = QTab(2), (2 = max. Polynomgrad)
165
          ce1 <= '1';--starten mul
166
          ce2 <= '0';
167
          ce3 <= '0';
168
          ce4 <= '0';
169
          stateafkt <= 1;-- Dann Auswertung gestartet
170
        ELSE
171
          Padd <= X"00000000";
172
          Qadd <= X"00000000";
173
          stateafkt <= 0;
174
        END IF;
175
        ---------------------------------
176
      WHEN 1 => -- ausführen  mul : Xinp * Ptab(2),Xinp * Qtab(2),   
177
          ce1 <= '0'; -- reset
178
          
179
          -- Pmul,Qmul sind bereit
180
            -- Decrement Tab-Index
181
          TabIdx := TabIdx - 1;
182
          PKoeff <= PTab(TabIdx);
183
          QKoeff <= QTab(TabIdx);
184
          stateafkt <= 2;
185
      WHEN 2 =>
186
          Pplus <= Pmul;
187
          Qplus <= Qmul;
188
          ce2 <= '1';
189
          stateafkt <= 3;
190
      When 3 =>
191
          ce2 <= '0';
192
          stateafkt <= 4;
193
      When 4 =>
194
          Padd <= Pa;
195
          Qadd <= Qa;
196
          IF TabIdx = 0 THEN
197
            Pplus <= X"00000000";
198
            Qplus <= X"00000000";
199
            ce3 <= '1';-- start div
200
            count := 1;
201
            stateafkt <= 5; -- und div
202
          ELSE
203
            Pinp <= Pa;
204
            Qinp <= Qa;
205
            ce1 <= '1';  -- start für Pmul,Qmul    
206
            stateafkt <= 1; -- und wiederholen
207
          END IF;
208
      WHEN 5 =>  -- div fertig
209
        IF count > 0 THEN
210
          count := count - 1;
211
          ce3 <= '0';
212
          stateafkt <= 5;
213
        ELSE
214
            stateafkt <= 0;--un warten auf neustart
215
        END IF;
216
      WHEN OTHERS =>
217
          stateafkt <= 0;
218
      END CASE; -- stateafkt
219
    END IF; -- nrst
220
  END IF; --clk
221
END PROCESS; --end pafkt
222
223
--=========Components Implementation====================================
224
-- ce1
225
cPmul:    mulFP port map(a=>Xinp, b=>Pinp, clk=>clk, ce=>ce1, result=>Pmul);
226
cQmul:    mulFP port map(a=>Xinp, b=>Qinp, clk=>clk, ce=>ce1, result=>Qmul);
227
-- ce2
228
cPadd:     addFP port map(a=>Pplus, b=>PKoeff, clk=>clk, ce=>ce2, result=>Pa);--
229
cQadd:     addFP port map(a=>Qplus, b=>QKoeff, clk=>clk, ce=>ce2, result=>Qa);--
230
-- ce3
231
cPQdiv:    divFP port map(a=>Padd, b=>Qadd,clk=>clk, ce=>ce3,result=>aout);
232
233
--===============================================================================00
234
end Behavioral;