assume input x is 16 bits signed
y_out is 16 bits signed
coeffs 16 bits signed
then you can either use integer computation or signed.
to simplify example, let us assume we can truncate y_int below without check,
I also assume a coeff of say 2 means 2 in terms of gain.
This code is untested but should give you an idea.
signal y1 : signed(32 downto 0) := (others => '0');
signal y2 : signed(33 downto 0) := (others => '0');
signal y_int : signed(34 downto 0) := (others => '0');
constant b0 : signed(15 downto 0) := x"0001";
constant b1 : signed(15 downto 0) := x"0002";
constant b2 : signed(15 downto 0) := x"0003";
constant a1 : signed(15 downto 0) := x"0002";
constant a2 : signed(15 downto 0) := x"0001";
begin
process
begin
wait until clk = '1';
y1 <= x*b2 + y_int(15 downto 0)*a2; -- 16*16 + 16*16cbits, needs 33 bits
y2 <= x*b1 + y_int(15 downto 0)*a1 + y1; -- 16*16 + 16*16 + 33bits, needs 34 bits
end process;
y_int <= x*b0 + y2; -- 16 * 16 + 34 bits, requires 35 bits
y <= y_int(15 downto 0);