--------------------------------------------------------------------------------
-- 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_sys is
Generic
(
	nbits_in		: integer := 12;
	nbits_in_frac	: integer := 12;
	nbits_out		: integer := 12;
	nbits_out_frac	: integer := 12;
	pipe_latency	: integer := 2;
	round_style		: fixed_round_style_type := fixed_truncate;
	overflow_style	: fixed_overflow_style_type := fixed_wrap
);
Port
(
	rst			: in std_logic;
	clk			: in std_logic;
	ce			: in std_logic;
	x_in		: in sfixed;
	y_in		: in sfixed;
	h_in		: in sfixed;
	x_out		: out sfixed;
	y_out		: out sfixed;
	vld_out		: out std_logic
);
end fir_stage_sys;

architecture Behavioral of fir_stage_sys is

subtype in_t is sfixed(shi(nbits_in, nbits_in_frac) downto slo(nbits_in, nbits_in_frac));
subtype out_t is sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac));

signal yin		: in_t;
signal prod		: out_t;
signal x_reg	: out_t;
signal y_reg	: out_t;
signal vld		: unsigned(pipe_latency-1 downto 0);

------------------------------------------------------------
begin

	assert pipe_latency = 2 report "Pipe latency must be two !" severity failure;

	yin			<= resize(y_in, yin);
	vld_out		<= vld(vld'left);
	y_out		<= y_reg;
	
------------------------------------------------------------
	proc_out_reg: process(clk)
	begin
		if rising_edge(clk) then
			if rst = '1' then 
				vld		<= (others => '0');
			elsif ce = '1' then
				vld		<= vld(vld'left-1 downto 0) & '1';
				prod	<= resize(x_in * h_in, prod, overflow_style, round_style);
				x_reg	<= resize(x_in, x_reg, overflow_style, round_style);
				y_reg	<= resize(yin + prod, y_reg, overflow_style, round_style);
				x_out	<= x_reg;
			end if;	
		end	if;
	end process;

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