-------------------------------------------------------------
-- MSS copyright 2015-2016
-- Filename:  FORWARD_STATE_GEN.VHD
-- Authors: 
--		Alain Zarembowitch / MSS
-- Version: Rev 1
-- Last modified: 9/15/16

-- Inheritance: 	N/A
--
-- description:  Generate forward state metrics a(k+1,s) from the previous state metrics a(k,s')
-------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity FORWARD_STATE_GEN is
	generic (
		NLLRBITS: integer := 11;
			-- LLR precision (for flexibility, even though NLLRBITS may end up being the same as NSMBITS, but could possibly be smaller)
		NSMBITS: integer := 22
			-- state metrics precision. 	
	);
    Port ( 
		--GLOBAL CLOCKS
		CLK: std_logic;
		SYNC_RESET: in std_logic;	-- unused here.
		
		-- Inputs
		-- Forward state metrics at time k
		A_IN0 : IN std_logic_vector((NSMBITS-1) downto 0);          
		A_IN1: IN std_logic_vector((NSMBITS-1) downto 0);          
		A_IN2 : IN std_logic_vector((NSMBITS-1) downto 0);          
		A_IN3 : IN std_logic_vector((NSMBITS-1) downto 0);          
		A_IN4 : IN std_logic_vector((NSMBITS-1) downto 0);          
		A_IN5 : IN std_logic_vector((NSMBITS-1) downto 0);          
		A_IN6 : IN std_logic_vector((NSMBITS-1) downto 0);          
		A_IN7 : IN std_logic_vector((NSMBITS-1) downto 0);          
		A_IN8 : IN std_logic_vector((NSMBITS-1) downto 0);          
		A_IN9 : IN std_logic_vector((NSMBITS-1) downto 0);          
		A_IN10 : IN std_logic_vector((NSMBITS-1) downto 0);          
		A_IN11 : IN std_logic_vector((NSMBITS-1) downto 0);          
		A_IN12 : IN std_logic_vector((NSMBITS-1) downto 0);          
		A_IN13 : IN std_logic_vector((NSMBITS-1) downto 0);          
		A_IN14 : IN std_logic_vector((NSMBITS-1) downto 0);          
		A_IN15 : IN std_logic_vector((NSMBITS-1) downto 0);      

		-- branch metrics at time k
		-- The index I in BM(I) represents ABYW, where A is the LSb and W the MSb.
		-- (keeping it the same order as in /Matlab/turbo.m)
		BM0 : in std_logic_vector(NLLRBITS-1 downto 0);          
		BM1 : in std_logic_vector(NLLRBITS-1 downto 0);           
		BM2 : in std_logic_vector(NLLRBITS-1 downto 0);      
		BM3 : in std_logic_vector(NLLRBITS-1 downto 0);           
		BM4 : in std_logic_vector(NLLRBITS-1 downto 0);           
		BM5 : in std_logic_vector(NLLRBITS-1 downto 0);         
		BM6 : in std_logic_vector(NLLRBITS-1 downto 0);          
		BM7 : in std_logic_vector(NLLRBITS-1 downto 0);          
		BM8 : in std_logic_vector(NLLRBITS-1 downto 0);          
		BM9 : in std_logic_vector(NLLRBITS-1 downto 0);          
		BM10 : in std_logic_vector(NLLRBITS-1 downto 0);          
		BM11 : in std_logic_vector(NLLRBITS-1 downto 0);          
		BM12 : in std_logic_vector(NLLRBITS-1 downto 0);          
		BM13 : in std_logic_vector(NLLRBITS-1 downto 0);          
		BM14 : in std_logic_vector(NLLRBITS-1 downto 0);          
		BM15 : in std_logic_vector(NLLRBITS-1 downto 0);
		


		-- Forward state metrics at time k+1
		-- Latency: 1 CLK
		A_OUT0 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		A_OUT1 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		A_OUT2 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		A_OUT3 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		A_OUT4 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		A_OUT5 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		A_OUT6 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		A_OUT7 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		A_OUT8 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		A_OUT9 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		A_OUT10 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		A_OUT11 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		A_OUT12 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		A_OUT13 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		A_OUT14 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		A_OUT15 : OUT std_logic_vector((NSMBITS-1) downto 0)       

  );
end entity;

architecture Behavioral of FORWARD_STATE_GEN is
--------------------------------------------------------
--      COMPONENTS
--------------------------------------------------------
--------------------------------------------------------
--     SIGNALS
--------------------------------------------------------
-- Suffix _D indicates a one CLK delayed version of the net with the same name
-- Suffix _X 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

-- Table td3 generated in Matlab file /matlab/turbo.m
-- columns: input state, ab, output state, yw, abyw		
-- ordered by output states and information ab
--     0     0     0     0     0
--     1     1     0     3    13
--    10     2     0     3    14
--    11     3     0     0     3
--     3     0     1     1     4
--     2     1     1     2     9
--     9     2     1     2    10
--     8     3     1     1     7
--     4     0     2     3    12
--     5     1     2     0     1
--    14     2     2     0     2
--    15     3     2     3    15
--     7     0     3     2     8
--     6     1     3     1     5
--    13     2     3     1     6
--    12     3     3     2    11
--     8     0     4     1     4
--     9     1     4     2     9
--     2     2     4     2    10
--     3     3     4     1     7
--    11     0     5     0     0
--    10     1     5     3    13
--     1     2     5     3    14
--     0     3     5     0     3
--    12     0     6     2     8
--    13     1     6     1     5
--     6     2     6     1     6
--     7     3     6     2    11
--    15     0     7     3    12
--    14     1     7     0     1
--     5     2     7     0     2
--     4     3     7     3    15
--     1     0     8     0     0
--     0     1     8     3    13
--    11     2     8     3    14
--    10     3     8     0     3
--     2     0     9     1     4
--     3     1     9     2     9
--     8     2     9     2    10
--     9     3     9     1     7
--     5     0    10     3    12
--     4     1    10     0     1
--    15     2    10     0     2
--    14     3    10     3    15
--     6     0    11     2     8
--     7     1    11     1     5
--    12     2    11     1     6
--    13     3    11     2    11
--     9     0    12     1     4
--     8     1    12     2     9
--     3     2    12     2    10
--     2     3    12     1     7
--    10     0    13     0     0
--    11     1    13     3    13
--     0     2    13     3    14
--     1     3    13     0     3
--    13     0    14     2     8
--    12     1    14     1     5
--     7     2    14     1     6
--     6     3    14     2    11
--    14     0    15     3    12
--    15     1    15     0     1
--     4     2    15     0     2
--     5     3    15     3    15
signal AS0_B0: signed((NSMBITS-1) downto 0) := (others => '0');    
signal AS0_B1: signed((NSMBITS-1) downto 0) := (others => '0');   
signal AS0_B2: signed((NSMBITS-1) downto 0) := (others => '0');   
signal AS0_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS1_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS1_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS1_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS1_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS2_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS2_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS2_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS2_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS3_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS3_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS3_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS3_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS4_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS4_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS4_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS4_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS5_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS5_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS5_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS5_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS6_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS6_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS6_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS6_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS7_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS7_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS7_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS7_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS8_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS8_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS8_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS8_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS9_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS9_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS9_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS9_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS10_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS10_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS10_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS10_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS11_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS11_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS11_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS11_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS12_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS12_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS12_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS12_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS13_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS13_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS13_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS13_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS14_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS14_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS14_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS14_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS15_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS15_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS15_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS15_B3: signed((NSMBITS-1) downto 0) := (others => '0');  

signal AS0_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS0_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS1_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS1_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS2_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS2_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS3_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS3_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS4_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS4_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS5_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS5_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS6_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS6_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS7_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS7_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS8_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS8_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS9_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS9_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS10_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS10_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS11_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS11_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS12_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS12_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS13_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS13_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS14_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS14_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS15_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal AS15_B23: signed((NSMBITS-1) downto 0) := (others => '0');  


--------------------------------------------------------
--      IMPLEMENTATION
--------------------------------------------------------
begin

-- for branches go to from input state s at time k to state s' at (k+1)
-- follow the branches in table td3
AS0_B0 <= signed(A_IN0) + resize(signed(BM0),NSMBITS);
AS0_B1 <= signed(A_IN1) + resize(signed(BM13),NSMBITS);
AS0_B2 <= signed(A_IN10) + resize(signed(BM14),NSMBITS);
AS0_B3 <= signed(A_IN11) + resize(signed(BM3),NSMBITS);

AS1_B0 <= signed(A_IN3) + resize(signed(BM4),NSMBITS);
AS1_B1 <= signed(A_IN2) + resize(signed(BM9),NSMBITS);
AS1_B2 <= signed(A_IN9) + resize(signed(BM10),NSMBITS);
AS1_B3 <= signed(A_IN8) + resize(signed(BM7),NSMBITS);

AS2_B0 <= signed(A_IN4) + resize(signed(BM12),NSMBITS);
AS2_B1 <= signed(A_IN5) + resize(signed(BM1),NSMBITS);
AS2_B2 <= signed(A_IN14) + resize(signed(BM2),NSMBITS);
AS2_B3 <= signed(A_IN15) + resize(signed(BM15),NSMBITS);

AS3_B0 <= signed(A_IN7) + resize(signed(BM8),NSMBITS);
AS3_B1 <= signed(A_IN6) + resize(signed(BM5),NSMBITS);
AS3_B2 <= signed(A_IN13) + resize(signed(BM6),NSMBITS);
AS3_B3 <= signed(A_IN12) + resize(signed(BM11),NSMBITS);

AS4_B0 <= signed(A_IN8) + resize(signed(BM4),NSMBITS);
AS4_B1 <= signed(A_IN9) + resize(signed(BM9),NSMBITS);
AS4_B2 <= signed(A_IN2) + resize(signed(BM10),NSMBITS);
AS4_B3 <= signed(A_IN3) + resize(signed(BM7),NSMBITS);

AS5_B0 <= signed(A_IN11) + resize(signed(BM0),NSMBITS);
AS5_B1 <= signed(A_IN10) + resize(signed(BM13),NSMBITS);
AS5_B2 <= signed(A_IN1) + resize(signed(BM14),NSMBITS);
AS5_B3 <= signed(A_IN0) + resize(signed(BM3),NSMBITS);

AS6_B0 <= signed(A_IN12) + resize(signed(BM8),NSMBITS);
AS6_B1 <= signed(A_IN13) + resize(signed(BM5),NSMBITS);
AS6_B2 <= signed(A_IN6) + resize(signed(BM6),NSMBITS);
AS6_B3 <= signed(A_IN7) + resize(signed(BM11),NSMBITS);

AS7_B0 <= signed(A_IN15) + resize(signed(BM12),NSMBITS);
AS7_B1 <= signed(A_IN14) + resize(signed(BM1),NSMBITS);
AS7_B2 <= signed(A_IN5) + resize(signed(BM2),NSMBITS);
AS7_B3 <= signed(A_IN4) + resize(signed(BM15),NSMBITS);

AS8_B0 <= signed(A_IN1) + resize(signed(BM0),NSMBITS);
AS8_B1 <= signed(A_IN0) + resize(signed(BM13),NSMBITS);
AS8_B2 <= signed(A_IN11) + resize(signed(BM14),NSMBITS);
AS8_B3 <= signed(A_IN10) + resize(signed(BM3),NSMBITS);

AS9_B0 <= signed(A_IN2) + resize(signed(BM4),NSMBITS);
AS9_B1 <= signed(A_IN3) + resize(signed(BM9),NSMBITS);
AS9_B2 <= signed(A_IN8) + resize(signed(BM10),NSMBITS);
AS9_B3 <= signed(A_IN9) + resize(signed(BM7),NSMBITS);

AS10_B0 <= signed(A_IN5) + resize(signed(BM12),NSMBITS);
AS10_B1 <= signed(A_IN4) + resize(signed(BM1),NSMBITS);
AS10_B2 <= signed(A_IN15) + resize(signed(BM2),NSMBITS);
AS10_B3 <= signed(A_IN14) + resize(signed(BM15),NSMBITS);

AS11_B0 <= signed(A_IN6) + resize(signed(BM8),NSMBITS);
AS11_B1 <= signed(A_IN7) + resize(signed(BM5),NSMBITS);
AS11_B2 <= signed(A_IN12) + resize(signed(BM6),NSMBITS);
AS11_B3 <= signed(A_IN13) + resize(signed(BM11),NSMBITS);

AS12_B0 <= signed(A_IN9) + resize(signed(BM4),NSMBITS);
AS12_B1 <= signed(A_IN8) + resize(signed(BM9),NSMBITS);
AS12_B2 <= signed(A_IN3) + resize(signed(BM10),NSMBITS);
AS12_B3 <= signed(A_IN2) + resize(signed(BM7),NSMBITS);

AS13_B0 <= signed(A_IN10) + resize(signed(BM0),NSMBITS);
AS13_B1 <= signed(A_IN11) + resize(signed(BM13),NSMBITS);
AS13_B2 <= signed(A_IN0) + resize(signed(BM14),NSMBITS);
AS13_B3 <= signed(A_IN1) + resize(signed(BM3),NSMBITS);

AS14_B0 <= signed(A_IN13) + resize(signed(BM8),NSMBITS);
AS14_B1 <= signed(A_IN12) + resize(signed(BM5),NSMBITS);
AS14_B2 <= signed(A_IN7) + resize(signed(BM6),NSMBITS);
AS14_B3 <= signed(A_IN6) + resize(signed(BM11),NSMBITS);

AS15_B0 <= signed(A_IN14) + resize(signed(BM12),NSMBITS);
AS15_B1 <= signed(A_IN15) + resize(signed(BM1),NSMBITS);
AS15_B2 <= signed(A_IN4) + resize(signed(BM2),NSMBITS);
AS15_B3 <= signed(A_IN5) + resize(signed(BM15),NSMBITS);


-- find the max for each state
MAX_SEARCH_AS0A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS0_B0 > AS0_B1) then
			AS0_B01 <= AS0_B0;
		else
			AS0_B01 <= AS0_B1;
		end if;
		if(AS0_B2 > AS0_B3) then
			AS0_B23 <= AS0_B2;
		else
			AS0_B23 <= AS0_B3;
		end if;
	end if;
end process;
MAX_SEARCH_AS1A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS1_B0 > AS1_B1) then
			AS1_B01 <= AS1_B0;
		else
			AS1_B01 <= AS1_B1;
		end if;
		if(AS1_B2 > AS1_B3) then
			AS1_B23 <= AS1_B2;
		else
			AS1_B23 <= AS1_B3;
		end if;
	end if;
end process;
MAX_SEARCH_AS2A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS2_B0 > AS2_B1) then
			AS2_B01 <= AS2_B0;
		else
			AS2_B01 <= AS2_B1;
		end if;
		if(AS2_B2 > AS2_B3) then
			AS2_B23 <= AS2_B2;
		else
			AS2_B23 <= AS2_B3;
		end if;
	end if;
end process;
MAX_SEARCH_AS3A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS3_B0 > AS3_B1) then
			AS3_B01 <= AS3_B0;
		else
			AS3_B01 <= AS3_B1;
		end if;
		if(AS3_B2 > AS3_B3) then
			AS3_B23 <= AS3_B2;
		else
			AS3_B23 <= AS3_B3;
		end if;
	end if;
end process;
MAX_SEARCH_AS4A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS4_B0 > AS4_B1) then
			AS4_B01 <= AS4_B0;
		else
			AS4_B01 <= AS4_B1;
		end if;
		if(AS4_B2 > AS4_B3) then
			AS4_B23 <= AS4_B2;
		else
			AS4_B23 <= AS4_B3;
		end if;
	end if;
end process;
MAX_SEARCH_AS5A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS5_B0 > AS5_B1) then
			AS5_B01 <= AS5_B0;
		else
			AS5_B01 <= AS5_B1;
		end if;
		if(AS5_B2 > AS5_B3) then
			AS5_B23 <= AS5_B2;
		else
			AS5_B23 <= AS5_B3;
		end if;
	end if;
end process;
MAX_SEARCH_AS6A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS6_B0 > AS6_B1) then
			AS6_B01 <= AS6_B0;
		else
			AS6_B01 <= AS6_B1;
		end if;
		if(AS6_B2 > AS6_B3) then
			AS6_B23 <= AS6_B2;
		else
			AS6_B23 <= AS6_B3;
		end if;
	end if;
end process;
MAX_SEARCH_AS7A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS7_B0 > AS7_B1) then
			AS7_B01 <= AS7_B0;
		else
			AS7_B01 <= AS7_B1;
		end if;
		if(AS7_B2 > AS7_B3) then
			AS7_B23 <= AS7_B2;
		else
			AS7_B23 <= AS7_B3;
		end if;
	end if;
end process;
MAX_SEARCH_AS8A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS8_B0 > AS8_B1) then
			AS8_B01 <= AS8_B0;
		else
			AS8_B01 <= AS8_B1;
		end if;
		if(AS8_B2 > AS8_B3) then
			AS8_B23 <= AS8_B2;
		else
			AS8_B23 <= AS8_B3;
		end if;
	end if;
end process;
MAX_SEARCH_AS9A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS9_B0 > AS9_B1) then
			AS9_B01 <= AS9_B0;
		else
			AS9_B01 <= AS9_B1;
		end if;
		if(AS9_B2 > AS9_B3) then
			AS9_B23 <= AS9_B2;
		else
			AS9_B23 <= AS9_B3;
		end if;
	end if;
end process;
MAX_SEARCH_AS10A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS10_B0 > AS10_B1) then
			AS10_B01 <= AS10_B0;
		else
			AS10_B01 <= AS10_B1;
		end if;
		if(AS10_B2 > AS10_B3) then
			AS10_B23 <= AS10_B2;
		else
			AS10_B23 <= AS10_B3;
		end if;
	end if;
end process;
MAX_SEARCH_AS11A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS11_B0 > AS11_B1) then
			AS11_B01 <= AS11_B0;
		else
			AS11_B01 <= AS11_B1;
		end if;
		if(AS11_B2 > AS11_B3) then
			AS11_B23 <= AS11_B2;
		else
			AS11_B23 <= AS11_B3;
		end if;
	end if;
end process;
MAX_SEARCH_AS12A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS12_B0 > AS12_B1) then
			AS12_B01 <= AS12_B0;
		else
			AS12_B01 <= AS12_B1;
		end if;
		if(AS12_B2 > AS12_B3) then
			AS12_B23 <= AS12_B2;
		else
			AS12_B23 <= AS12_B3;
		end if;
	end if;
end process;
MAX_SEARCH_AS13A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS13_B0 > AS13_B1) then
			AS13_B01 <= AS13_B0;
		else
			AS13_B01 <= AS13_B1;
		end if;
		if(AS13_B2 > AS13_B3) then
			AS13_B23 <= AS13_B2;
		else
			AS13_B23 <= AS13_B3;
		end if;
	end if;
end process;
MAX_SEARCH_AS14A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS14_B0 > AS14_B1) then
			AS14_B01 <= AS14_B0;
		else
			AS14_B01 <= AS14_B1;
		end if;
		if(AS14_B2 > AS14_B3) then
			AS14_B23 <= AS14_B2;
		else
			AS14_B23 <= AS14_B3;
		end if;
	end if;
end process;
MAX_SEARCH_AS15A: process(CLK)
begin
	if rising_edge(CLK) then
		if(AS15_B0 > AS15_B1) then
			AS15_B01 <= AS15_B0;
		else
			AS15_B01 <= AS15_B1;
		end if;
		if(AS15_B2 > AS15_B3) then
			AS15_B23 <= AS15_B2;
		else
			AS15_B23 <= AS15_B3;
		end if;
	end if;
end process;


-- 1 CLK latency to output
MAX_SEARCH_AS0B: process(AS0_B01, AS0_B23)
begin
		if(AS0_B01 > AS0_B23) then
			A_OUT0 <= std_logic_vector(AS0_B01);
		else
			A_OUT0 <= std_logic_vector(AS0_B23);
		end if;
end process;
MAX_SEARCH_AS1B: process(AS1_B01, AS1_B23)
begin
		if(AS1_B01 > AS1_B23) then
			A_OUT1 <= std_logic_vector(AS1_B01);
		else
			A_OUT1 <= std_logic_vector(AS1_B23);
		end if;
end process;
MAX_SEARCH_AS2B: process(AS2_B01, AS2_B23)
begin
		if(AS2_B01 > AS2_B23) then
			A_OUT2 <= std_logic_vector(AS2_B01);
		else
			A_OUT2 <= std_logic_vector(AS2_B23);
		end if;
end process;
MAX_SEARCH_AS3B: process(AS3_B01, AS3_B23)
begin
		if(AS3_B01 > AS3_B23) then
			A_OUT3 <= std_logic_vector(AS3_B01);
		else
			A_OUT3 <= std_logic_vector(AS3_B23);
		end if;
end process;
MAX_SEARCH_AS4B: process(AS4_B01, AS4_B23)
begin
		if(AS4_B01 > AS4_B23) then
			A_OUT4 <= std_logic_vector(AS4_B01);
		else
			A_OUT4 <= std_logic_vector(AS4_B23);
		end if;
end process;
MAX_SEARCH_AS5B: process(AS5_B01, AS5_B23)
begin
		if(AS5_B01 > AS5_B23) then
			A_OUT5 <= std_logic_vector(AS5_B01);
		else
			A_OUT5 <= std_logic_vector(AS5_B23);
		end if;
end process;
MAX_SEARCH_AS6B: process(AS6_B01, AS6_B23)
begin
		if(AS6_B01 > AS6_B23) then
			A_OUT6 <= std_logic_vector(AS6_B01);
		else
			A_OUT6 <= std_logic_vector(AS6_B23);
		end if;
end process;
MAX_SEARCH_AS7B: process(AS7_B01, AS7_B23)
begin
		if(AS7_B01 > AS7_B23) then
			A_OUT7 <= std_logic_vector(AS7_B01);
		else
			A_OUT7 <= std_logic_vector(AS7_B23);
		end if;
end process;
MAX_SEARCH_AS8B: process(AS8_B01, AS8_B23)
begin
		if(AS8_B01 > AS8_B23) then
			A_OUT8 <= std_logic_vector(AS8_B01);
		else
			A_OUT8 <= std_logic_vector(AS8_B23);
		end if;
end process;
MAX_SEARCH_AS9B: process(AS9_B01, AS9_B23)
begin
		if(AS9_B01 > AS9_B23) then
			A_OUT9 <= std_logic_vector(AS9_B01);
		else
			A_OUT9 <= std_logic_vector(AS9_B23);
		end if;
end process;
MAX_SEARCH_AS10B: process(AS10_B01, AS10_B23)
begin
		if(AS10_B01 > AS10_B23) then
			A_OUT10 <= std_logic_vector(AS10_B01);
		else
			A_OUT10 <= std_logic_vector(AS10_B23);
		end if;
end process;
MAX_SEARCH_AS11B: process(AS11_B01, AS11_B23)
begin
		if(AS11_B01 > AS11_B23) then
			A_OUT11 <= std_logic_vector(AS11_B01);
		else
			A_OUT11 <= std_logic_vector(AS11_B23);
		end if;
end process;
MAX_SEARCH_AS12B: process(AS12_B01, AS12_B23)
begin
		if(AS12_B01 > AS12_B23) then
			A_OUT12 <= std_logic_vector(AS12_B01);
		else
			A_OUT12 <= std_logic_vector(AS12_B23);
		end if;
end process;
MAX_SEARCH_AS13B: process(AS13_B01, AS13_B23)
begin
		if(AS13_B01 > AS13_B23) then
			A_OUT13 <= std_logic_vector(AS13_B01);
		else
			A_OUT13 <= std_logic_vector(AS13_B23);
		end if;
end process;
MAX_SEARCH_AS14B: process(AS14_B01, AS14_B23)
begin
		if(AS14_B01 > AS14_B23) then
			A_OUT14 <= std_logic_vector(AS14_B01);
		else
			A_OUT14 <= std_logic_vector(AS14_B23);
		end if;
end process;
MAX_SEARCH_AS15B: process(AS15_B01, AS15_B23)
begin
		if(AS15_B01 > AS15_B23) then
			A_OUT15 <= std_logic_vector(AS15_B01);
		else
			A_OUT15 <= std_logic_vector(AS15_B23);
		end if;
end process;
	

end Behavioral;

