library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.std_logic_unsigned.all; library lpm; use lpm.lpm_components.all; entity lpm_divide_self_operands_gen is generic ( numerator_width : natural := 64; denominator_width : natural := 39; quotient_width : natural := 64 ); port( clk : in std_logic; ce : in std_logic; rst : in std_logic; keep_divs_output : out std_logic ); end lpm_divide_self_operands_gen; architecture structural of lpm_divide_self_operands_gen is signal s_lpm_rst : std_logic; signal s_numerator : std_logic_vector(numerator_width-1 downto 0); signal s_denominator : std_logic_vector(denominator_width-1 downto 0); signal s_factors_dv : std_logic; signal s_remainder : std_logic_vector(denominator_width-1 downto 0); signal s_quotient : std_logic_vector(quotient_width-1 downto 0); -- constant INITIAL_WAIT : natural := 200000000; -- 2 seconds constant INITIAL_WAIT : natural := 200000; -- 2 seconds constant INITIAL_WAIT_COUNTER_WIDTH : natural := 28; signal s_initial_wait_counter : unsigned(INITIAL_WAIT_COUNTER_WIDTH-1 downto 0); constant OPERANDS_PERIOD : natural := 10; -- 10 CLOCK PERIODS constant OPERANDS_PERIOD_COUNTER_WIDTH : natural := 4; signal s_operands_period_counter : unsigned(OPERANDS_PERIOD_COUNTER_WIDTH-1 downto 0); constant N_OPERANDS : natural := 1000; constant OPERANDS_COUNTER_WIDTH : natural := 10; signal s_operands_counter : unsigned(OPERANDS_COUNTER_WIDTH-1 downto 0); constant NUMERATOR_INIT_VAL : std_logic_vector(numerator_width-1 downto 0) := x"FFFFFFEC78000000"; constant NUMERATOR_STEP : std_logic_vector(numerator_width-1 downto 0) := std_logic_vector(to_signed(167772160,numerator_width)); constant DENOMINATOR_INIT_VAL : std_logic_vector(denominator_width-1 downto 0) := std_logic_vector(to_unsigned(1,denominator_width)); constant DENOMINATOR_STEP : std_logic_vector(denominator_width-1 downto 0) := std_logic_vector(to_unsigned(10,denominator_width)); begin operands_gen_proc: process(clk,rst) begin if (rst = '0') then s_numerator <= NUMERATOR_INIT_VAL; s_denominator <= DENOMINATOR_INIT_VAL; s_factors_dv <= '0'; s_operands_period_counter <= (others => '0'); s_initial_wait_counter <= (others => '0'); s_operands_counter <= (others => '0'); elsif (clk'event and clk = '1') then if (clk = '1') then if (ce = '1') then if (s_initial_wait_counter = INITIAL_WAIT-1) then if (s_operands_period_counter = OPERANDS_PERIOD-1) then s_operands_period_counter <= (others => '0'); s_factors_dv <= '1'; if (s_operands_counter = N_OPERANDS-1) then s_numerator <= NUMERATOR_INIT_VAL; s_denominator <= DENOMINATOR_INIT_VAL; s_operands_counter <= (others => '0'); else s_numerator <= std_logic_vector(signed(s_numerator) + signed(NUMERATOR_STEP)); s_denominator <= std_logic_vector(unsigned(s_denominator) + unsigned(DENOMINATOR_STEP)); s_operands_counter <= s_operands_counter + 1; end if; else s_factors_dv <= '0'; s_operands_period_counter <= s_operands_period_counter+1; end if; else s_initial_wait_counter <= s_initial_wait_counter+1; end if; end if; end if; end if; end process operands_gen_proc; s_lpm_rst <= not(rst); keep_proc:process(clk,rst) begin if (rst = '0') then keep_divs_output <= '0'; elsif (clk'event and clk = '1') then if (ce = '1') then if ((signed(s_quotient)>0) or (signed(s_remainder) > 0)) then keep_divs_output <= '1'; else keep_divs_output <= '0'; end if; end if; end if; end process keep_proc; div_component: LPM_DIVIDE generic map ( LPM_WIDTHN => numerator_width, LPM_WIDTHD => denominator_width, LPM_NREPRESENTATION =>"SIGNED", LPM_DREPRESENTATION =>"UNSIGNED", LPM_PIPELINE => 66, LPM_TYPE => L_DIVIDE, LPM_HINT =>"UNUSED" ) port map ( NUMER => s_numerator, DENOM => s_denominator, ACLR => s_lpm_rst, CLOCK => clk, CLKEN => ce, QUOTIENT => s_quotient, REMAIN => s_remainder ); end structural;