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