-------------------------------------------------------------
-- MSS copyright 1999-2001
--	Filename:  ENCODER_K7R2.VHD
-- Author: Alain Zarembowitch / MSS
--	Version: 0.001
--	Date last modified: 12-29-01
-- Inheritance: 	none
--
-- description:  
-- COM-1010
-- Convolutional encoder. K = 7, R = 1/2
---------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ENCODER_K7R2 is
    port ( 
		--GLOBAL CLOCKS, RESET
	   CLK : in std_logic;	-- master clock for this FPGA, synchronous 
		ASYNC_RESET: in std_logic;	-- asynchronous reset

		--// Input samples
		DATA_IN: in std_logic;
			-- input bit. Read at rising edge of CLK when SAMPLE_CLK_IN = '1';
		SAMPLE_CLK_IN: in std_logic;
			-- one CLK-wide pulse
	  	SOF_RESET: in std_logic;
			-- 1 CLK-wide pulse indicating that the encoder shall be reset. 
			-- Aligned with SAMPLE_CLK_IN.
			-- Used in the block mode. 

		--// Output samples
		DATA_OUT: out std_logic_vector(1 downto 0);
			-- output sample. Read at rising edge of CLK when SAMPLE_CLK_IN = '1';
			-- 2-bit parallel output
		SAMPLE_CLK_OUT: out std_logic
			-- one CLK-wide pulse. same rate as SAMPLE_CLK_IN
			-- Latency is 1 CLK.
		
			);
end entity;

architecture behavioral of ENCODER_K7R2 is
--------------------------------------------------------
--      COMPONENTS
--------------------------------------------------------

--------------------------------------------------------
--     SIGNALS
--------------------------------------------------------
-- Suffix _D indicates a one CLK delayed version of the net with the same name
-- Suffix _E indicates an extended precision version of the net with the same name
-- Suffix _N indicates an inverted version of the net with the same name
signal REG6: std_logic_vector(5 downto 0);
signal G0: std_logic;
signal G1: std_logic;
--------------------------------------------------------
--      IMPLEMENTATION
--------------------------------------------------------

begin

--// clock input bit into 6-delay register 
RECLOCK_001: process(ASYNC_RESET, CLK)
begin
	if(ASYNC_RESET = '1') then
		REG6 <= (others => '0');
	elsif rising_edge(CLK) then  
   	if(SOF_RESET = '1') then
			-- reset register. block mode.
			REG6(0) <= DATA_IN;
			REG6(5 downto 1) <= (others => '0');
		elsif(SAMPLE_CLK_IN = '1') then
			REG6(0) <= DATA_IN;
			REG6(5 downto 1) <= REG6(4 downto 0);
	  	end if;
	end if;
end process;

--// Generator polynomials
--G0(x) = 1 + x2 + x3 + x5 + x6
--G1(x) = 1 + x + x2 + x3 + x6

G0 <= DATA_IN xor REG6(1) xor REG6(2) xor REG6(4) xor REG6(5);
G1 <= DATA_IN xor REG6(0) xor REG6(1) xor REG6(2) xor REG6(5);

-- Reclock output
-- 1 CLK latency
OUTPUT_001: process(ASYNC_RESET, CLK)
begin
	if(ASYNC_RESET = '1') then
		DATA_OUT <= (others => '0');
		SAMPLE_CLK_OUT <= '0';
	elsif rising_edge(CLK) then  
		if(SAMPLE_CLK_IN = '1') then
			DATA_OUT(0) <= G0;
			DATA_OUT(1) <= G1;
	  	end if;
		SAMPLE_CLK_OUT <= SAMPLE_CLK_IN;
	end if;
end process;


end behavioral;
