--------------------------------------------------------------------------------
-- Company: 
-- Engineer:
--
-- Create Date:    12:16:14 10/02/05
-- Design Name:    
-- Module Name:    fir_stage - Behavioral
-- Project Name:   
-- Target Device:  
-- Tool versions:  
-- Description:
--
-- Dependencies:
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- 
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.MATH_REAL.ALL;
USE ieee.numeric_std.ALL;

library ieee_proposed;
use ieee_proposed.fixed_float_types.all;
use ieee_proposed.fixed_pkg.all;

library work;
use work.utils_pkg.all;
use work.fixed_util_pkg.all;
use work.fir_pkg.all;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity fir_stage is
Generic
(
	nbits_in		: integer := 12;
	nbits_in_frac	: integer := 12;
	nbits_out		: integer := 12;
	nbits_out_frac	: integer := 12;
	has_in_reg		: boolean := false;
	has_pipe_reg	: boolean := false;
	has_out_reg		: boolean := false;
	fir_mode		: fir_stage_mode_t := transposed;
	rounding		: boolean := true;
	saturating		: boolean := true
);
Port
(
	srst		: in std_logic;
	clk			: in std_logic;
	in_valid	: in std_logic;
	x_in		: in sfixed;
	y_in		: in sfixed;
	h_in		: in sfixed;
	out_valid	: out std_logic;
	x_out		: out sfixed;
	y_out		: out sfixed;
	y_out_clr	: in std_logic
);
end fir_stage;

architecture Behavioral of fir_stage is

signal xin : sfixed(shi(nbits_in, nbits_in_frac) downto slo(nbits_in, nbits_in_frac));
signal yin : sfixed(shi(nbits_in, nbits_in_frac) downto slo(nbits_in, nbits_in_frac));
signal hin : sfixed(shi(nbits_in, nbits_in_frac) downto slo(nbits_in, nbits_in_frac));
signal prod : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac));
signal valid, p_valid : std_logic;
------------------------------------------------------------
begin


------------------------------------------------------------
	proc_in_reg_y: process(clk)
	begin
		if rising_edge(clk) then
			if srst = '1' or y_out_clr = '1' then
				yin <= to_sfixed(0, yin);
			else	
				yin <= resize(y_in, yin);
			end if;	
		end	if;
	end process;

------------------------------------------------------------
	proc_in_reg_hx: process(srst, clk, in_valid, x_in, h_in)
	variable p : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac));
	begin
		if has_in_reg = true then
			if rising_edge(clk) then
				if srst = '1' then
					xin <= to_sfixed(0, xin);
					hin <= to_sfixed(0, hin);
					valid <= '0';
				else
					valid <= in_valid;
					if in_valid = '1' then
						xin <= resize(x_in, xin);
						hin <= resize(h_in, hin);
					end if;
				end if;
			end if;
		else
			xin <= resize(x_in, xin);
			hin <= resize(h_in, hin);
			valid <= in_valid;
		end if;
		x_out <= resize(x_in, p);
		
	end process;

------------------------------------------------------------
	proc_pipe_reg: process(srst, clk, valid, xin, hin)
	variable p : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac));
	begin
		p := resize(xin * hin, p);
		if has_pipe_reg = true then
			if rising_edge(clk) then
				if srst = '1' then
					prod  <= to_sfixed(0, prod);
					p_valid <= '0';
				else
					prod  <= p;
					p_valid <= valid;
				end if;	
			end if;	
		else	
			prod  <= p;
			p_valid <= valid;
		end if;	
	end process;
	
------------------------------------------------------------
	proc_out_reg: process(srst, clk, p_valid, prod, yin)
	variable yout : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac));
	begin
		yout := resize(yin + prod, yout, fixed_wrap, fixed_truncate);
--		if rising_edge(clk) then
--			if srst = '1' or y_out_clr = '1' then
--				y_out <= to_sfixed(0, yout);
--				out_valid <= '0';
--			else	
--				y_out <= yout;
--				out_valid <= p_valid;
--			end if;	
--		end	if;
		out_valid <= p_valid;
		y_out <= yout;
	end process;

------------------------------------------------------------
end Behavioral;
