]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/commitdiff
Reduce sine and cosine to 16-bit only variant in approximated function block.
authorPavel Pisa <ppisa@pikron.com>
Sun, 7 Dec 2014 10:53:57 +0000 (11:53 +0100)
committerPavel Pisa <ppisa@pikron.com>
Sun, 7 Dec 2014 10:53:57 +0000 (11:53 +0100)
It is far above target application needs and implementation
with last result bits stripped reduces FPGA slices utilization.

Signed-off-by: Pavel Pisa <ppisa@pikron.com>
hw/lx-fncapprox/lx_fncapprox.vhd

index 26732a7ac71ccb52c4593814ace8ef76735caea8..53692b966a7c07cdf25a92ced4ab06c29098198b 100644 (file)
@@ -362,6 +362,7 @@ result_registers_write:
        process(state_regw_r, dsp48_p_s, sin_cos_negate_out_r2, sin_cos_force_one_r2,
                reci_result_r, sin_result_r, cos_result_r)
                variable sin_cos_res_v  : std_logic_vector(31 downto 0);
+               variable sin_cos_res_short_v  : std_logic_vector(17 downto 0);
        begin
                reci_result_s <= reci_result_r;
                sin_result_s <= sin_result_r;
@@ -373,10 +374,19 @@ result_registers_write:
                        sin_cos_res_v := dsp48_p_s(approx_tab_b_shift + 35 -1 downto approx_tab_b_shift + 4 - 1);
                end if;
 
+               -- Precise 2'nd complement
+               -- if sin_cos_negate_out_r2 = '1' then
+               --      sin_cos_res_v := std_logic_vector(-signed(sin_cos_res_v));
+                -- end if;
+
+               -- Fast imprecise first complement
                if sin_cos_negate_out_r2 = '1' then
-                       sin_cos_res_v := std_logic_vector(-signed(sin_cos_res_v));
+                       sin_cos_res_v := not sin_cos_res_v;
                 end if;
 
+               sin_cos_res_short_v := std_logic_vector(unsigned(sin_cos_res_v(31 downto 14)) +
+                                                       unsigned(sin_cos_res_v(13 downto 13)));
+
                case state_regw_r is
                        when ST_IDLE =>
                                null;
@@ -391,13 +401,15 @@ result_registers_write:
                                null;
 
                        when ST_SIN1 =>
-                               sin_result_s <= sin_cos_res_v;
+                               sin_result_s(17 downto 0) <= sin_cos_res_short_v;
+                               sin_result_s(31 downto 18) <= (others => sin_cos_res_short_v(17));
 
                        when ST_COS0 =>
                                null;
 
                        when ST_COS1 =>
-                               cos_result_s <= sin_cos_res_v;
+                               cos_result_s(17 downto 0) <= sin_cos_res_short_v;
+                               cos_result_s(31 downto 18) <= (others => sin_cos_res_short_v(17));
 
                end case;
        end process;
@@ -409,23 +421,13 @@ wire_out:
 
                if ce_s = '1' then
                        if address_s(4 downto 0) = "00000" then
-                               data_o <= x"12345678";
+                               data_o <= x"FA00000E";
                        elsif address_s(4 downto 0) = "00001" then
                                data_o <= reci_result_r;
                        elsif address_s(4 downto 0) = "00010" then
                                data_o <= sin_result_r;
                        elsif address_s(4 downto 0) = "00011" then
                                data_o <= cos_result_r;
-                       elsif address_s(4 downto 0) = "00100" then
-                               data_o(17 downto 0) <= sin_result_r(31 downto 14);
-                               data_o(31 downto 18) <= (others => sin_result_r(31));
-                       elsif address_s(4 downto 0) = "00101" then
-                               data_o(17 downto 0) <= cos_result_r(31 downto 14);
-                               data_o(31 downto 18) <= (others => cos_result_r(31));
-                       elsif address_s(4 downto 0) = "00110" then
-                               data_o <= x"ABCDEF01";
-                       elsif address_s(4 downto 0) = "00111" then
-                               data_o <= argument_r;
                        else
                                data_o <= (others => '0');
                        end if;