func_c.vhd


1
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: A.Kurka 
4
-- 
5
-- Create Date:   16.05.2021
6
-- modified   : 16.05.2021 A.K 
7
-- Module Name:    func_c - Behavioral 
8
-- Project Name: AS21
9
-- Target Devices: 
10
-- Tool versions: ISE 14.7
11
-- Description: Funktion für cosFP
12
-- func_c[0,PI^2] = (P0 + X*(P1 + X*P2)) / (Q0 + X*(Q1 + X*Q2));
13
-- cos(X) = func_c(X^2);
14
----------------------------------------------------------------------------------
15
library IEEE;
16
use IEEE.STD_LOGIC_1164.ALL;
17
use IEEE.STD_LOGIC_ARITH.ALL;
18
use IEEE.STD_LOGIC_UNSIGNED.ALL;
19
20
21
entity func_c is
22
port(  nrst  : in std_logic;
23
      clk    : in std_logic;
24
      cefktC  : in std_logic; -- startimpuls afkt
25
      Xinp    : in std_logic_vector(31 downto 0); -- Input in [0, 0.5] in FP-Format
26
      aout    : OUT std_logic_vector(31 downto 0) -- Output in [1, 1.047197+] in FP-Format, 1.047197=2*asin(0.5)
27
      );
28
end func_c;
29
30
architecture Behavioral of func_c is
31
----------------------------------------------------
32
COMPONENT mulFP IS
33
  port (
34
  a: IN std_logic_VECTOR(31 downto 0);
35
  b: IN std_logic_VECTOR(31 downto 0);
36
  clk: IN std_logic;
37
  ce: IN std_logic;
38
  result: OUT std_logic_VECTOR(31 downto 0));
39
END COMPONENT;
40
---------------------------------------------
41
COMPONENT addFP 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 divFP 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
TYPE T_PQTab IS ARRAY(0 TO 3) OF std_logic_vector(31 DOWNTO 0); -- Koeff Tabelle
60
--koeffizienten Tabellen für P , MinMax Approximation
61
CONSTANT PTab :T_PQTab:= -- alle werte in FP
62
(
63
X"4859d8dc",--P0  +  index 0
64
X"c7cc8cac",--P1  -
65
X"45bb6448",--P2  +              index 2
66
X"c29c3bf6"             
67
);
68
--------------------------------
69
CONSTANT QTab :T_PQTab:= -- alle werte in FP
70
(
71
X"4859d8dc",--Q0  +1039.057684548               index 0
72
X"45d4c345",--Q1  +46.49394241313
73
X"42d3bc9b",--Q2  +1.0   indesx 2
74
X"3f800000"
75
);  
76
--==================== Signale für afkt ==================================
77
SIGNAL statefktC  :integer range 0 to 7:= 0;
78
--SIGNAL ceafkt   :std_logic:='0';-- Startimpuls afkt, extern
79
SIGNAL ce1      :std_logic:='0';-- Start Pmul = Xinp*Pinp;   Qmul = Xinp*Qinp
80
SIGNAL ce2      :std_logic:='0';-- Start Padd = Pmul+PKoeff; Qadd = Qmul+QKoeff
81
SIGNAL ce3      :std_logic:='0';-- Start  Pplus/Qplus zuweisung
82
SIGNAL ce4      :std_logic:='0';-- Start aout = Pplus/Qplus
83
SIGNAL Pinp      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- 2. Input cPmul
84
SIGNAL Qinp      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- 2. input cQmul
85
86
SIGNAL Pmul      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPmul
87
SIGNAL Qmul      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cQmul
88
SIGNAL Pplus    :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPmul
89
SIGNAL Qplus    :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cQmul
90
SIGNAL Pa      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPadd
91
SIGNAL Qa      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPadd
92
SIGNAL Padd      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cPadd, Ergebnis Auswertung P()
93
SIGNAL Qadd      :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Resultat cQadd, Ergebnis Auswertung Q()
94
SIGNAL PKoeff    :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Koeff von P()
95
SIGNAL QKoeff    :std_logic_vector(31 DOWNTO 0):=X"00000000";-- Koeff von Q()
96
--================================================================
97
98
--==========================================================================
99
begin
100
--=================================================================
101
--************************************************************************ 
102
pfkt_C:PROCESS(clk) -- Process für fktC(Xinp)  für cosFP berechnung.
103
-- Loop Counter läuft von 1 = MAX(deg_P,deg_Q) - 1 bis 0 und dient
104
-- als Index in PTab und QTab.
105
106
VARIABLE TabIdx : INTEGER RANGE 0 TO 3 := 0;
107
VARIABLE count :INTEGER RANGE 0 TO 7;
108
BEGIN
109
  IF rising_edge(clk) THEN  
110
    IF nrst = '0' THEN 
111
      TabIdx := 0; -- just 0's
112
      PKoeff <= X"00000000"; -- Not-a-Number
113
      QKoeff <= X"00000000"; -- Not-a-Number
114
      Pinp   <= X"00000000"; -- Not-a-Number
115
      Qinp   <= X"00000000"; -- Not-a-Number
116
      ce1 <= '0';
117
      ce2 <= '0';
118
      ce4 <= '0';
119
      count := 0;
120
      statefktC <= 0;
121
    ELSE
122
      CASE statefktC IS
123
        WHEN 0 => -- Start afkt
124
          IF cefktC = '1' THEN
125
            TabIdx := 3; -- Init Index in Tabellen (1 = max. Polynomgrad - 1)--****************.
126
            Pinp <= PTab(3); -- Init Pinp = PTab(2), (2 = max. Polynomgrad)
127
            Qinp <= QTab(3); -- Init Qinp = QTab(2), (2 = max. Polynomgrad)
128
            ce1 <= '1';--starten mul
129
            ce2 <= '0';
130
            ce3 <= '0';
131
            ce4 <= '0';
132
            statefktC <= 1;-- Dann Auswertung gestartet
133
          ELSE
134
            Padd <= X"00000000";
135
            Qadd <= X"00000000";
136
            statefktC <= 0;
137
          END IF;
138
        ---------------------------------
139
        WHEN 1 => -- ausführen  mul : Xinp * Ptab(2),Xinp * Qtab(2),
140
          ce1 <= '0'; -- reset            
141
          ce2 <= '1'; -- start add
142
          -- Pmul,Qmul sind bereit
143
            -- Decrement Tab-Index
144
          TabIdx := TabIdx - 1;
145
          PKoeff <= PTab(TabIdx);
146
          QKoeff <= QTab(TabIdx);
147
          statefktC <= 2;
148
      WHEN 2 => --  add = Pmul + PKoeff
149
          ce2 <= '0'; -- reset
150
          IF TabIdx = 0 THEN
151
            -- letzte schlaufen Addition,zu P0,Q0 Addition
152
            Padd <= Pmul;--input für Add 2 setzen
153
            Qadd <= Qmul;
154
            ce3 <= '1'; --start Pplus Qplus
155
            statefktC <= 4;
156
          ELSE
157
            statefktC <= 3;
158
          END IF;
159
      WHEN 3 =>
160
            Padd <= Pa;
161
            Qadd <= Qa;
162
            Pinp <= Pa;
163
            Qinp <= Qa;
164
            ce1 <= '1';
165
            statefktC <= 1;
166
      WHEN 4 => --Run Add p0,q0
167
          ce3 <= '0';
168
          ce4 <= '1'; --start für div P/Q div
169
          Count := 1;
170
          statefktC <= 5; -- und warten auf Neustart
171
      WHEN 5 =>
172
        IF count > 0 THEN
173
          count := count - 1;
174
          ce4 <= '0';
175
          statefktC <= 5;
176
        ELSE
177
          statefktC <= 0;
178
        END IF;
179
      WHEN OTHERS =>
180
          statefktC <= 0;
181
      END CASE; -- stateafkt
182
    END IF; -- nrst
183
  END IF; --clk
184
END PROCESS; --end pafkt
185
186
187
--=========Components Implementation====================================
188
-- ce1
189
cPmul:    mulFP port map(a=>Xinp, b=>Pinp, clk=>clk, ce=>ce1, result=>Pmul);
190
cQmul:    mulFP port map(a=>Xinp, b=>Qinp, clk=>clk, ce=>ce1, result=>Qmul);
191
-- ce2
192
cPadd:     addFP port map(a=>Pmul, b=>PKoeff, clk=>clk, ce=>ce2, result=>Pa);--
193
cQadd:     addFP port map(a=>Qmul, b=>QKoeff, clk=>clk, ce=>ce2, result=>Qa);--
194
-- cPplus könnte man sich zwahr sparen, in dem  cPadd zweimal verwendet wird
195
-- daführ kostet es ein CLK mehr
196
-- ce3
197
cPplus:     addFP port map(a=>Padd, b=>PKoeff, clk=>clk, ce=>ce3, result=>Pplus);--
198
cQplus:     addFP port map(a=>Qadd, b=>QKoeff, clk=>clk, ce=>ce3, result=>Qplus);--
199
-- ce4
200
cPQdiv:    divFP port map(a=>Pplus, b=>Qplus, clk=>clk, ce=>ce4, result=>aout);
201
202
203
204
end Behavioral;