I know many tell you to use two or three processes for fsm but I only trust using one single clocked process. This avoids the clutter of code and combinatorial issues.
Try this change(not tested obviously)
process (n_pur, clk)
begin
if n_pur='0' then
asd_cs <= standby;
lock <= '0';
rate <= "00000";
rate_tmp1 <= "00000";
asd_pass_reg <= 0;
lock_tmp <= '0';
state_tmp <= '0';
rate_tmp <= "00000";
counter_fsm_en <= '0';
asd_pass <= 0;
elsif rising_edge (clk) then
lock <= lock_tmp;
rate <= rate_tmp;
rate_tmp1 <= rate_tmp;
asd_pass_reg <= asd_pass;
case asd_cs is
when standby =>
lock_tmp <= '0';
state_tmp <= '0';
rate_tmp <= rate_tmp1;
counter_fsm_en <= '0';
asd_pass <= 0;
if enable = '1' then
asd_cs <= detecting;
end if;
when detecting =>
lock_tmp <= '0';
state_tmp <= '1';
rate_tmp <= rate_tmp1;
counter_fsm_en <= '1';
if s2_rate = last_detected_rate and s2_rate /= "00000" and output='1' then
asd_pass <= asd_pass_reg+1;
else
asd_pass <= 0;
end if;
if enable = '0' then
asd_cs <= standby;
elsif asd_pass >= asd_max_pass-1 then
asd_cs <= locked;
end if;
when locked =>
lock_tmp <= '1';
state_tmp <= '0';
rate_tmp <= s2_rate;
counter_fsm_en <= '0';
asd_pass <= 0;
if enable = '0' then
asd_cs <= standby;
end if;
when others => null;
end case;
end if;
end process;