]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/lx-fncapprox/lx_fncapprox.vhd
Table C for reciprocal computation reduced to made DSP48 structure same as for sine.
[fpga/lx-cpu1/lx-rocon.git] / hw / lx-fncapprox / lx_fncapprox.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_unsigned.all;
4 use ieee.numeric_std.all;
5 use work.mbl_pkg.all;
6 use work.lx_rocon_pkg.all;
7
8 -- IRC bus interconnect
9 entity lx_fncapprox is
10         port
11         (
12                 clk_i        : in std_logic;
13                 reset_i      : in std_logic;
14                 -- Data bus
15                 address_i    : in std_logic_vector(4 downto 0);
16                 next_ce_i    : in std_logic;
17                 data_i       : in std_logic_vector(31 downto 0);
18                 data_o       : out std_logic_vector(31 downto 0);
19                 --
20                 bls_i        : in std_logic_vector(3 downto 0)
21         );
22 end lx_fncapprox;
23
24 architecture Behavioral of lx_fncapprox is
25
26         component rom_table
27         generic
28         (
29                 data_width : integer;
30                 addr_width : integer;
31                 init_file  : string
32         );
33         port
34         (
35                 ack_o  : out std_logic;
36                 addr_i : in  std_logic_vector (addr_width-1 downto 0);
37                 clk_i  : in  std_logic;
38                 data_o : out std_logic_vector (data_width-1 downto 0);
39                 stb_i  : in  std_logic
40         );
41         end component;
42
43         constant approx_tab_bits    : natural := 8;
44         constant approx_frac_bits   : natural := 18;
45
46         constant reci_tab_b_shift   : natural := 9;
47         constant reci_tab_c_shift   : natural := 25;
48
49         signal ce_s                 : std_logic;
50
51         signal approx_tab_idx_s     : std_logic_vector(approx_tab_bits-1 downto 0);
52         signal approx_tab_idx_r     : std_logic_vector(approx_tab_bits-1 downto 0);
53         signal approx_frac_s        : std_logic_vector(approx_frac_bits-1 downto 0);
54         signal approx_frac_r        : std_logic_vector(approx_frac_bits-1 downto 0);
55         signal reci_tab_a_data_s    : std_logic_vector(35 downto 0);
56         signal reci_tab_a_data_r    : std_logic_vector(35 downto 0);
57         signal reci_tab_bc_data_s   : std_logic_vector(35 downto 0);
58         signal reci_tab_bc_data_r   : std_logic_vector(35 downto 0);
59
60         signal reci_tab_b_shifted_r : std_logic_vector(47 downto 0);
61         signal reci_tab_a_shifted_r : std_logic_vector(47 downto 0);
62         signal frac_c_mult_s        : std_logic_vector(47 downto 0);
63         signal frac2_bc_mult_s      : std_logic_vector(47 downto 0);
64
65         signal approx_result_s      : std_logic_vector(31 downto 0);
66
67         signal reci_tab_a_ack_s     : std_logic;
68         signal reci_tab_a_ack_r     : std_logic;
69         signal reci_tab_a_stb_s     : std_logic;
70
71         signal reci_tab_bc_ack_s    : std_logic;
72         signal reci_tab_bc_ack_r    : std_logic;
73         signal reci_tab_bc_stb_s    : std_logic;
74 begin
75
76 reci_tab_a : rom_table
77         generic map (
78                 data_width => 36,
79                 addr_width => approx_tab_bits,
80                 init_file  => "reci_tab_a.lut"
81         )
82         port map
83         (
84                 clk_i  => clk_i,
85                 stb_i  => reci_tab_a_stb_s,
86                 addr_i => approx_tab_idx_s,
87                 data_o => reci_tab_a_data_s,
88                 ack_o  => reci_tab_a_ack_s
89         );
90
91 reci_tab_bc : rom_table
92         generic map (
93                 data_width => 36,
94                 addr_width => approx_tab_bits,
95                 init_file  => "reci_tab_bc.lut"
96         )
97         port map
98         (
99                 clk_i  => clk_i,
100                 stb_i  => reci_tab_bc_stb_s,
101                 addr_i => approx_tab_idx_s,
102                 data_o => reci_tab_bc_data_s,
103                 ack_o  => reci_tab_bc_ack_s
104         );
105
106 wire_in:
107         process(next_ce_i, ce_s, bls_i, address_i, data_i, approx_tab_idx_r, approx_frac_r)
108         begin
109                 -- init values
110                 reci_tab_a_stb_s     <= '0';
111                 reci_tab_bc_stb_s     <= '0';
112                 approx_tab_idx_s <= approx_tab_idx_r;
113                 approx_frac_s <= approx_frac_r;
114
115                 -- Incoming bus request
116                 if next_ce_i = '1' then
117                         if bls_i(0) = '1' then
118                                 reci_tab_a_stb_s <= '1';
119                                 reci_tab_bc_stb_s <= '1';
120                                 approx_tab_idx_s <= data_i(30 downto
121                                            30 - approx_tab_bits + 1);
122                                 approx_frac_s <= data_i(30 - approx_tab_bits downto
123                                            30 - approx_tab_bits - approx_frac_bits + 1);
124                         end if;
125                 end if;
126         end process;
127
128 wire_out:
129         process(ce_s, approx_result_s)
130         begin
131
132                 data_o <= (others => '0');
133
134                 if ce_s = '1' then
135                         data_o <= approx_result_s;
136                 end if;
137         end process;
138
139 update:
140         process
141         begin
142                 wait until clk_i'event and clk_i= '1';
143                 ce_s      <= next_ce_i;
144                 if reci_tab_a_ack_s = '1' then
145                         reci_tab_a_data_r <= reci_tab_a_data_s;
146                 end if;
147                 if reci_tab_bc_ack_s = '1' then
148                         reci_tab_bc_data_r <= reci_tab_bc_data_s;
149                 end if;
150
151                 -- yl = reci_tab_a[ti];
152                 -- yl -= ((reci_tab_b[ti] - ((reci_tab_c[ti] * xd) >> RECI_TAB_C_SHIFT)) * xd) >> RECI_TAB_B_SHIFT;
153
154                 reci_tab_b_shifted_r(reci_tab_c_shift - 1 downto 0) <= (others => '0');
155                 reci_tab_b_shifted_r(reci_tab_c_shift + 17 downto reci_tab_c_shift) <= reci_tab_bc_data_r(35 downto 18);
156                 reci_tab_b_shifted_r(47 downto reci_tab_c_shift + 18) <= (others => '0');
157
158                 frac_c_mult_s <= std_logic_vector(unsigned(reci_tab_b_shifted_r) -
159                         (unsigned(reci_tab_bc_data_r(17 downto 0)) * unsigned(approx_frac_r)));
160
161                 reci_tab_a_shifted_r(reci_tab_b_shift - 1 downto 0) <= (others => '0');
162                 reci_tab_a_shifted_r(reci_tab_b_shift + 35 downto reci_tab_b_shift) <= reci_tab_a_data_r;
163                 reci_tab_a_shifted_r(47 downto reci_tab_b_shift + 36) <= (others => '0');
164
165                 frac2_bc_mult_s <= std_logic_vector(unsigned(reci_tab_a_shifted_r) -
166                         unsigned(frac_c_mult_s(reci_tab_c_shift + 17 downto reci_tab_c_shift)) *
167                         unsigned(approx_frac_r));
168
169                 approx_result_s <= frac2_bc_mult_s(reci_tab_b_shift + 35 downto reci_tab_b_shift + 4);
170
171                 reci_tab_a_ack_r <= reci_tab_a_ack_s;
172                 reci_tab_bc_ack_r <= reci_tab_bc_ack_s;
173                 approx_tab_idx_r <= approx_tab_idx_s;
174                 approx_frac_r <= approx_frac_s;
175         end process;
176
177 end Behavioral;
178