library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; use work.mbl_pkg.all; use work.lx_rocon_pkg.all; -- IRC bus interconnect entity lx_fncapprox is port ( clk_i : in std_logic; reset_i : in std_logic; -- Data bus address_i : in std_logic_vector(4 downto 0); next_ce_i : in std_logic; data_i : in std_logic_vector(31 downto 0); data_o : out std_logic_vector(31 downto 0); -- bls_i : in std_logic_vector(3 downto 0) ); end lx_fncapprox; architecture Behavioral of lx_fncapprox is component rom_table generic ( data_width : integer; addr_width : integer; init_file : string ); port ( ack_o : out std_logic; addr_i : in std_logic_vector (addr_width-1 downto 0); clk_i : in std_logic; data_o : out std_logic_vector (data_width-1 downto 0); stb_i : in std_logic ); end component; constant approx_tab_bits : natural := 8; constant approx_frac_bits : natural := 18; constant reci_tab_b_shift : natural := 9; constant reci_tab_c_shift : natural := 25; signal ce_s : std_logic; signal approx_tab_idx_s : std_logic_vector(approx_tab_bits-1 downto 0); signal approx_tab_idx_r : std_logic_vector(approx_tab_bits-1 downto 0); signal approx_frac_s : std_logic_vector(approx_frac_bits-1 downto 0); signal approx_frac_r : std_logic_vector(approx_frac_bits-1 downto 0); signal reci_tab_a_data_s : std_logic_vector(35 downto 0); signal reci_tab_a_data_r : std_logic_vector(35 downto 0); signal reci_tab_bc_data_s : std_logic_vector(35 downto 0); signal reci_tab_bc_data_r : std_logic_vector(35 downto 0); signal reci_tab_b_shifted_r : std_logic_vector(47 downto 0); signal reci_tab_a_shifted_r : std_logic_vector(47 downto 0); signal frac_c_mult_s : std_logic_vector(47 downto 0); signal frac2_bc_mult_s : std_logic_vector(47 downto 0); signal approx_result_s : std_logic_vector(31 downto 0); signal reci_tab_a_ack_s : std_logic; signal reci_tab_a_ack_r : std_logic; signal reci_tab_a_stb_s : std_logic; signal reci_tab_bc_ack_s : std_logic; signal reci_tab_bc_ack_r : std_logic; signal reci_tab_bc_stb_s : std_logic; begin reci_tab_a : rom_table generic map ( data_width => 36, addr_width => approx_tab_bits, init_file => "reci_tab_a.lut" ) port map ( clk_i => clk_i, stb_i => reci_tab_a_stb_s, addr_i => approx_tab_idx_s, data_o => reci_tab_a_data_s, ack_o => reci_tab_a_ack_s ); reci_tab_bc : rom_table generic map ( data_width => 36, addr_width => approx_tab_bits, init_file => "reci_tab_bc.lut" ) port map ( clk_i => clk_i, stb_i => reci_tab_bc_stb_s, addr_i => approx_tab_idx_s, data_o => reci_tab_bc_data_s, ack_o => reci_tab_bc_ack_s ); wire_in: process(next_ce_i, ce_s, bls_i, address_i, data_i, approx_tab_idx_r, approx_frac_r) begin -- init values reci_tab_a_stb_s <= '0'; reci_tab_bc_stb_s <= '0'; approx_tab_idx_s <= approx_tab_idx_r; approx_frac_s <= approx_frac_r; -- Incoming bus request if next_ce_i = '1' then if bls_i(0) = '1' then reci_tab_a_stb_s <= '1'; reci_tab_bc_stb_s <= '1'; approx_tab_idx_s <= data_i(30 downto 30 - approx_tab_bits + 1); approx_frac_s <= data_i(30 - approx_tab_bits downto 30 - approx_tab_bits - approx_frac_bits + 1); end if; end if; end process; wire_out: process(ce_s, approx_result_s) begin data_o <= (others => '0'); if ce_s = '1' then data_o <= approx_result_s; end if; end process; update: process begin wait until clk_i'event and clk_i= '1'; ce_s <= next_ce_i; if reci_tab_a_ack_s = '1' then reci_tab_a_data_r <= reci_tab_a_data_s; end if; if reci_tab_bc_ack_s = '1' then reci_tab_bc_data_r <= reci_tab_bc_data_s; end if; -- yl = reci_tab_a[ti]; -- yl -= ((reci_tab_b[ti] - ((reci_tab_c[ti] * xd) >> RECI_TAB_C_SHIFT)) * xd) >> RECI_TAB_B_SHIFT; reci_tab_b_shifted_r(reci_tab_c_shift - 1 downto 0) <= (others => '0'); reci_tab_b_shifted_r(reci_tab_c_shift + 17 downto reci_tab_c_shift) <= reci_tab_bc_data_r(35 downto 18); reci_tab_b_shifted_r(47 downto reci_tab_c_shift + 18) <= (others => '0'); frac_c_mult_s <= std_logic_vector(unsigned(reci_tab_b_shifted_r) - (unsigned(reci_tab_bc_data_r(17 downto 0)) * unsigned(approx_frac_r))); reci_tab_a_shifted_r(reci_tab_b_shift - 1 downto 0) <= (others => '0'); reci_tab_a_shifted_r(reci_tab_b_shift + 35 downto reci_tab_b_shift) <= reci_tab_a_data_r; reci_tab_a_shifted_r(47 downto reci_tab_b_shift + 36) <= (others => '0'); frac2_bc_mult_s <= std_logic_vector(unsigned(reci_tab_a_shifted_r) - unsigned(frac_c_mult_s(reci_tab_c_shift + 17 downto reci_tab_c_shift)) * unsigned(approx_frac_r)); approx_result_s <= frac2_bc_mult_s(reci_tab_b_shift + 35 downto reci_tab_b_shift + 4); reci_tab_a_ack_r <= reci_tab_a_ack_s; reci_tab_bc_ack_r <= reci_tab_bc_ack_s; approx_tab_idx_r <= approx_tab_idx_s; approx_frac_r <= approx_frac_s; end process; end Behavioral;