-------------------------------------------------------------
-- MSS copyright 2016
-- Filename:  TC_DECODER_DVB_RCS2.VHD
-- Authors: 
--		Alain Zarembowitch / MSS
-- Version: Rev 0
-- Last modified: 11/7/15

-- Inheritance: 	N/A
--
-- description:  DVB-RCS2 turbo codec configuration
-- User enters the burst payload size (in BYTES) and the coding rate R1/R2. This component
-- looks up the optimum detailed configuration in Table-A1 of ETSI EN 301 545-2.
-------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity TC_CODEC_CONFIG is
    Port ( 
		--GLOBAL CLOCKS
		CLK: std_logic;
		SYNC_RESET: in std_logic;
		
		-- SIMPLE CONFIGURATION (INPUT)
		BURST_PAYLOAD_SIZE: in std_logic_vector(9 downto 0);
			-- range 1 - 1000 BYTES
		R1: in std_logic_vector(2 downto 0);
		R2: in std_logic_vector(3 downto 0);
			-- encoding rate R1/R2
			-- Valid entries  1/3, 1/2, 2/3, 3/4, 5/6
		
		-- DETAILED CONFIGURATION (OUTPUT)
		-- See ETSI EN 300 545 table 9-2
		-- one MUST apply a SYNC_RESET pulse to activate these controls
		P: out std_logic_vector(6 downto 0);
			-- range 9 - 81
		Q0: out std_logic_vector(3 downto 0);	
		Q1: out std_logic_vector(3 downto 0);
		Q2: out std_logic_vector(3 downto 0);
			-- range 0 - 15
		Q3: out std_logic_vector(2 downto 0);
			-- range 0 - 5
		Y_PUNCTURING_PERIOD: out std_logic_vector(4 downto 0);
			-- 1 - 28 bits
		Y_PUNCTURING_PATTERN: out std_logic_vector(27 downto 0);
			-- read from right (bit 0) to left (bit Y_PUNCTURING_PERIOD-1) 
			-- right-aligned. MSbs may be unused, depending on the period.
			-- therefore the patterns in Annex A must be flipped.
		W_PUNCTURING_PATTERN: out std_logic
			
		  );
end entity;

architecture Behavioral of TC_CODEC_CONFIG is
--------------------------------------------------------
--      COMPONENTS
--------------------------------------------------------
component TC_CODEC_TABLEA1
	 Generic (
		DATA_WIDTH: integer;	
		ADDR_WIDTH: integer
	);
    Port ( 
	    -- Port A
		CLKA   : in  std_logic;
		CSA: in std_logic;	-- chip select, active high
		OEA : in std_logic;	-- output enable, active high
		ADDRA  : in  std_logic_vector(ADDR_WIDTH-1 downto 0);
		DOA  : out std_logic_vector(DATA_WIDTH-1 downto 0);

		-- Port B
		CLKB   : in  std_logic;
		CSB: in std_logic;	-- chip select, active high
		OEB : in std_logic;	-- output enable, active high
		ADDRB  : in  std_logic_vector(ADDR_WIDTH-1 downto 0);
		DOB  : out std_logic_vector(DATA_WIDTH-1 downto 0)
		);
end component;
--------------------------------------------------------
--     SIGNALS
--------------------------------------------------------
signal WAVEFORM: integer range 0 to 63 := 0;
signal DOA: std_logic_vector(63  downto 0) := (others => '0');
--------------------------------------------------------
--      IMPLEMENTATION
--------------------------------------------------------
begin

-- Waveform IDs, as per Table-A1
WAVEFORM_IDs_001: process(CLK)
begin
	if rising_edge(CLK) then
		if(unsigned(BURST_PAYLOAD_SIZE) = 38) and (unsigned(R1) = 1) and (unsigned(R2) = 3) then
			WAVEFORM <= 1;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 14) and (unsigned(R1) = 1) and (unsigned(R2) = 3) then
			WAVEFORM <= 2;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 59) and (unsigned(R1) = 1) and (unsigned(R2) = 2) then
			WAVEFORM <= 4;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 85) and (unsigned(R1) = 2) and (unsigned(R2) = 3) then
			WAVEFORM <= 5;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 96) and (unsigned(R1) = 3) and (unsigned(R2) = 4) then
			WAVEFORM <= 6;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 108) and (unsigned(R1) = 5) and (unsigned(R2) = 6) then
			WAVEFORM <= 7;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 115) and (unsigned(R1) = 2) and (unsigned(R2) = 3) then
			WAVEFORM <= 8;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 130) and (unsigned(R1) = 3) and (unsigned(R2) = 4) then
			WAVEFORM <= 9;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 144) and (unsigned(R1) = 5) and (unsigned(R2) = 6) then
			WAVEFORM <= 10;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 175) and (unsigned(R1) = 3) and (unsigned(R2) = 4) then
			WAVEFORM <= 11;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 194) and (unsigned(R1) = 5) and (unsigned(R2) = 6) then
			WAVEFORM <= 12;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 123) and (unsigned(R1) = 1) and (unsigned(R2) = 3) then
			WAVEFORM <= 13;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 188) and (unsigned(R1) = 1) and (unsigned(R2) = 2) then
			WAVEFORM <= 14;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 264) and (unsigned(R1) = 2) and (unsigned(R2) = 3) then
			WAVEFORM <= 15;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 298) and (unsigned(R1) = 3) and (unsigned(R2) = 4) then
			WAVEFORM <= 16;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 333) and (unsigned(R1) = 5) and (unsigned(R2) = 6) then
			WAVEFORM <= 17;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 355) and (unsigned(R1) = 2) and (unsigned(R2) = 3) then
			WAVEFORM <= 18;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 400) and (unsigned(R1) = 3) and (unsigned(R2) = 4) then
			WAVEFORM <= 19;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 444) and (unsigned(R1) = 5) and (unsigned(R2) = 6) then
			WAVEFORM <= 20;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 539) and (unsigned(R1) = 3) and (unsigned(R2) = 4) then
			WAVEFORM <= 21;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 599) and (unsigned(R1) = 5) and (unsigned(R2) = 6) then
			WAVEFORM <= 22;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 100) and (unsigned(R1) = 1) and (unsigned(R2) = 2) then
			WAVEFORM <= 32;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 100) and (unsigned(R1) = 3) and (unsigned(R2) = 4) then
			WAVEFORM <= 33;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 170) and (unsigned(R1) = 1) and (unsigned(R2) = 2) then
			WAVEFORM <= 34;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 170) and (unsigned(R1) = 3) and (unsigned(R2) = 4) then
			WAVEFORM <= 35;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 170) and (unsigned(R1) = 7) and (unsigned(R2) = 8) then
			WAVEFORM <= 36;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 438) and (unsigned(R1) = 2) and (unsigned(R2) = 3) then
			WAVEFORM <= 37;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 438) and (unsigned(R1) = 4) and (unsigned(R2) = 5) then
			WAVEFORM <= 38;
		elsif(unsigned(BURST_PAYLOAD_SIZE) = 438) and (unsigned(R1) = 6) and (unsigned(R2) = 7) then
			WAVEFORM <= 39;
		else
			WAVEFORM <= 0;
		end if;
	end if;
end process;

-- lookup Table A-1  
TC_CODEC_TABLEA1_001: TC_CODEC_TABLEA1
	GENERIC MAP(
		DATA_WIDTH => 64,
		ADDR_WIDTH => 6
	)
    PORT MAP ( 
		CLKA => CLK,
		CSA => '1',
		OEA => '1',
		ADDRA => std_logic_vector(to_unsigned(WAVEFORM,6)),
		DOA => DOA,
		CLKB => CLK,
		CSB => '0',
		OEB => '0',
		ADDRB => (others => '0'),
		DOB => open
);
		
P <= DOA(6 downto 0);
Q0 <= DOA(10  downto 7);		
Q1 <= DOA(14  downto 11);		
Q2 <= DOA(18  downto 15);		
Q3 <= DOA(21  downto 19);	
Y_PUNCTURING_PERIOD <= 	DOA(26  downto 22);
Y_PUNCTURING_PATTERN <= 	DOA(54  downto 27);
W_PUNCTURING_PATTERN <= 	DOA(55);
		

end Behavioral;

