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

-- Inheritance: 	N/A
--
-- description:  Generate backward state metrics b(k,s) from the next state metrics b(k+1,s)
-------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity BACKWARD_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
		-- Backward state metrics at time k+1
		B_IN0 : IN std_logic_vector((NSMBITS-1) downto 0);          
		B_IN1: IN std_logic_vector((NSMBITS-1) downto 0);          
		B_IN2 : IN std_logic_vector((NSMBITS-1) downto 0);          
		B_IN3 : IN std_logic_vector((NSMBITS-1) downto 0);          
		B_IN4 : IN std_logic_vector((NSMBITS-1) downto 0);          
		B_IN5 : IN std_logic_vector((NSMBITS-1) downto 0);          
		B_IN6 : IN std_logic_vector((NSMBITS-1) downto 0);          
		B_IN7 : IN std_logic_vector((NSMBITS-1) downto 0);          
		B_IN8 : IN std_logic_vector((NSMBITS-1) downto 0);          
		B_IN9 : IN std_logic_vector((NSMBITS-1) downto 0);          
		B_IN10 : IN std_logic_vector((NSMBITS-1) downto 0);          
		B_IN11 : IN std_logic_vector((NSMBITS-1) downto 0);          
		B_IN12 : IN std_logic_vector((NSMBITS-1) downto 0);          
		B_IN13 : IN std_logic_vector((NSMBITS-1) downto 0);          
		B_IN14 : IN std_logic_vector((NSMBITS-1) downto 0);          
		B_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);

		-- Backward state metrics at time k
		-- Latency: 1 CLK
		B_OUT0 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		B_OUT1 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		B_OUT2 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		B_OUT3 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		B_OUT4 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		B_OUT5 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		B_OUT6 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		B_OUT7 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		B_OUT8 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		B_OUT9 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		B_OUT10 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		B_OUT11 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		B_OUT12 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		B_OUT13 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		B_OUT14 : OUT std_logic_vector((NSMBITS-1) downto 0);          
		B_OUT15 : OUT std_logic_vector((NSMBITS-1) downto 0)       

  );
end entity;

architecture Behavioral of BACKWARD_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 td generated in Matlab file /matlab/turbo.m
-- columns: input state, ab, output state, yw, abyw		
-- ordered by input states and information ab
--     0     0     0     0     0
--     0     1     8     3    13
--     0     2    13     3    14
--     0     3     5     0     3
--     1     0     8     0     0
--     1     1     0     3    13
--     1     2     5     3    14
--     1     3    13     0     3
--     2     0     9     1     4
--     2     1     1     2     9
--     2     2     4     2    10
--     2     3    12     1     7
--     3     0     1     1     4
--     3     1     9     2     9
--     3     2    12     2    10
--     3     3     4     1     7
--     4     0     2     3    12
--     4     1    10     0     1
--     4     2    15     0     2
--     4     3     7     3    15
--     5     0    10     3    12
--     5     1     2     0     1
--     5     2     7     0     2
--     5     3    15     3    15
--     6     0    11     2     8
--     6     1     3     1     5
--     6     2     6     1     6
--     6     3    14     2    11
--     7     0     3     2     8
--     7     1    11     1     5
--     7     2    14     1     6
--     7     3     6     2    11
--     8     0     4     1     4
--     8     1    12     2     9
--     8     2     9     2    10
--     8     3     1     1     7
--     9     0    12     1     4
--     9     1     4     2     9
--     9     2     1     2    10
--     9     3     9     1     7
--    10     0    13     0     0
--    10     1     5     3    13
--    10     2     0     3    14
--    10     3     8     0     3
--    11     0     5     0     0
--    11     1    13     3    13
--    11     2     8     3    14
--    11     3     0     0     3
--    12     0     6     2     8
--    12     1    14     1     5
--    12     2    11     1     6
--    12     3     3     2    11
--    13     0    14     2     8
--    13     1     6     1     5
--    13     2     3     1     6
--    13     3    11     2    11
--    14     0    15     3    12
--    14     1     7     0     1
--    14     2     2     0     2
--    14     3    10     3    15
--    15     0     7     3    12
--    15     1    15     0     1
--    15     2    10     0     2
--    15     3     2     3    15


signal BS0_B0: signed((NSMBITS-1) downto 0) := (others => '0');    
signal BS0_B1: signed((NSMBITS-1) downto 0) := (others => '0');   
signal BS0_B2: signed((NSMBITS-1) downto 0) := (others => '0');   
signal BS0_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS1_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS1_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS1_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS1_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS2_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS2_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS2_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS2_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS3_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS3_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS3_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS3_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS4_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS4_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS4_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS4_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS5_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS5_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS5_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS5_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS6_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS6_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS6_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS6_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS7_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS7_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS7_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS7_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS8_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS8_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS8_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS8_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS9_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS9_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS9_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS9_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS10_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS10_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS10_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS10_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS11_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS11_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS11_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS11_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS12_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS12_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS12_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS12_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS13_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS13_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS13_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS13_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS14_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS14_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS14_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS14_B3: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS15_B0: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS15_B1: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS15_B2: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS15_B3: signed((NSMBITS-1) downto 0) := (others => '0');  

signal BS0_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS0_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS1_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS1_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS2_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS2_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS3_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS3_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS4_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS4_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS5_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS5_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS6_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS6_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS7_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS7_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS8_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS8_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS9_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS9_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS10_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS10_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS11_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS11_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS12_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS12_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS13_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS13_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS14_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS14_B23: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS15_B01: signed((NSMBITS-1) downto 0) := (others => '0');  
signal BS15_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
BS0_B0 <= signed(B_IN0) + resize(signed(BM0),NSMBITS);
BS0_B1 <= signed(B_IN8) + resize(signed(BM13),NSMBITS);
BS0_B2 <= signed(B_IN13) + resize(signed(BM14),NSMBITS);
BS0_B3 <= signed(B_IN5) + resize(signed(BM3),NSMBITS);

BS1_B0 <= signed(B_IN8) + resize(signed(BM0),NSMBITS);
BS1_B1 <= signed(B_IN0) + resize(signed(BM13),NSMBITS);
BS1_B2 <= signed(B_IN5) + resize(signed(BM14),NSMBITS);
BS1_B3 <= signed(B_IN13) + resize(signed(BM3),NSMBITS);

BS2_B0 <= signed(B_IN9) + resize(signed(BM4),NSMBITS);
BS2_B1 <= signed(B_IN1) + resize(signed(BM9),NSMBITS);
BS2_B2 <= signed(B_IN4) + resize(signed(BM10),NSMBITS);
BS2_B3 <= signed(B_IN12) + resize(signed(BM7),NSMBITS);

BS3_B0 <= signed(B_IN1) + resize(signed(BM4),NSMBITS);
BS3_B1 <= signed(B_IN9) + resize(signed(BM9),NSMBITS);
BS3_B2 <= signed(B_IN12) + resize(signed(BM10),NSMBITS);
BS3_B3 <= signed(B_IN4) + resize(signed(BM7),NSMBITS);

BS4_B0 <= signed(B_IN2) + resize(signed(BM12),NSMBITS);
BS4_B1 <= signed(B_IN10) + resize(signed(BM1),NSMBITS);
BS4_B2 <= signed(B_IN15) + resize(signed(BM2),NSMBITS);
BS4_B3 <= signed(B_IN7) + resize(signed(BM15),NSMBITS);

BS5_B0 <= signed(B_IN10) + resize(signed(BM12),NSMBITS);
BS5_B1 <= signed(B_IN2) + resize(signed(BM1),NSMBITS);
BS5_B2 <= signed(B_IN7) + resize(signed(BM2),NSMBITS);
BS5_B3 <= signed(B_IN15) + resize(signed(BM15),NSMBITS);

BS6_B0 <= signed(B_IN11) + resize(signed(BM8),NSMBITS);
BS6_B1 <= signed(B_IN3) + resize(signed(BM5),NSMBITS);
BS6_B2 <= signed(B_IN6) + resize(signed(BM6),NSMBITS);
BS6_B3 <= signed(B_IN14) + resize(signed(BM11),NSMBITS);

BS7_B0 <= signed(B_IN3) + resize(signed(BM8),NSMBITS);
BS7_B1 <= signed(B_IN11) + resize(signed(BM5),NSMBITS);
BS7_B2 <= signed(B_IN14) + resize(signed(BM6),NSMBITS);
BS7_B3 <= signed(B_IN6) + resize(signed(BM11),NSMBITS);

BS8_B0 <= signed(B_IN4) + resize(signed(BM4),NSMBITS);
BS8_B1 <= signed(B_IN12) + resize(signed(BM9),NSMBITS);
BS8_B2 <= signed(B_IN9) + resize(signed(BM10),NSMBITS);
BS8_B3 <= signed(B_IN1) + resize(signed(BM7),NSMBITS);

BS9_B0 <= signed(B_IN12) + resize(signed(BM4),NSMBITS);
BS9_B1 <= signed(B_IN4) + resize(signed(BM9),NSMBITS);
BS9_B2 <= signed(B_IN1) + resize(signed(BM10),NSMBITS);
BS9_B3 <= signed(B_IN9) + resize(signed(BM7),NSMBITS);

BS10_B0 <= signed(B_IN13) + resize(signed(BM0),NSMBITS);
BS10_B1 <= signed(B_IN5) + resize(signed(BM13),NSMBITS);
BS10_B2 <= signed(B_IN0) + resize(signed(BM14),NSMBITS);
BS10_B3 <= signed(B_IN8) + resize(signed(BM3),NSMBITS);

BS11_B0 <= signed(B_IN5) + resize(signed(BM0),NSMBITS);
BS11_B1 <= signed(B_IN13) + resize(signed(BM13),NSMBITS);
BS11_B2 <= signed(B_IN8) + resize(signed(BM14),NSMBITS);
BS11_B3 <= signed(B_IN0) + resize(signed(BM3),NSMBITS);

BS12_B0 <= signed(B_IN6) + resize(signed(BM8),NSMBITS);
BS12_B1 <= signed(B_IN14) + resize(signed(BM5),NSMBITS);
BS12_B2 <= signed(B_IN11) + resize(signed(BM6),NSMBITS);
BS12_B3 <= signed(B_IN3) + resize(signed(BM11),NSMBITS);

BS13_B0 <= signed(B_IN14) + resize(signed(BM8),NSMBITS);
BS13_B1 <= signed(B_IN6) + resize(signed(BM5),NSMBITS);
BS13_B2 <= signed(B_IN3) + resize(signed(BM6),NSMBITS);
BS13_B3 <= signed(B_IN11) + resize(signed(BM11),NSMBITS);

BS14_B0 <= signed(B_IN15) + resize(signed(BM12),NSMBITS);
BS14_B1 <= signed(B_IN7) + resize(signed(BM1),NSMBITS);
BS14_B2 <= signed(B_IN2) + resize(signed(BM2),NSMBITS);
BS14_B3 <= signed(B_IN10) + resize(signed(BM15),NSMBITS);

BS15_B0 <= signed(B_IN7) + resize(signed(BM12),NSMBITS);
BS15_B1 <= signed(B_IN15) + resize(signed(BM1),NSMBITS);
BS15_B2 <= signed(B_IN10) + resize(signed(BM2),NSMBITS);
BS15_B3 <= signed(B_IN2) + resize(signed(BM15),NSMBITS);


-- find the max for each state
MAX_SEARCH_BS0A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS0_B0 > BS0_B1) then
			BS0_B01 <= BS0_B0;
		else
			BS0_B01 <= BS0_B1;
		end if;
		if(BS0_B2 > BS0_B3) then
			BS0_B23 <= BS0_B2;
		else
			BS0_B23 <= BS0_B3;
		end if;
	end if;
end process;
MAX_SEARCH_BS1A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS1_B0 > BS1_B1) then
			BS1_B01 <= BS1_B0;
		else
			BS1_B01 <= BS1_B1;
		end if;
		if(BS1_B2 > BS1_B3) then
			BS1_B23 <= BS1_B2;
		else
			BS1_B23 <= BS1_B3;
		end if;
	end if;
end process;
MAX_SEARCH_BS2A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS2_B0 > BS2_B1) then
			BS2_B01 <= BS2_B0;
		else
			BS2_B01 <= BS2_B1;
		end if;
		if(BS2_B2 > BS2_B3) then
			BS2_B23 <= BS2_B2;
		else
			BS2_B23 <= BS2_B3;
		end if;
	end if;
end process;
MAX_SEARCH_BS3A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS3_B0 > BS3_B1) then
			BS3_B01 <= BS3_B0;
		else
			BS3_B01 <= BS3_B1;
		end if;
		if(BS3_B2 > BS3_B3) then
			BS3_B23 <= BS3_B2;
		else
			BS3_B23 <= BS3_B3;
		end if;
	end if;
end process;
MAX_SEARCH_BS4A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS4_B0 > BS4_B1) then
			BS4_B01 <= BS4_B0;
		else
			BS4_B01 <= BS4_B1;
		end if;
		if(BS4_B2 > BS4_B3) then
			BS4_B23 <= BS4_B2;
		else
			BS4_B23 <= BS4_B3;
		end if;
	end if;
end process;
MAX_SEARCH_BS5A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS5_B0 > BS5_B1) then
			BS5_B01 <= BS5_B0;
		else
			BS5_B01 <= BS5_B1;
		end if;
		if(BS5_B2 > BS5_B3) then
			BS5_B23 <= BS5_B2;
		else
			BS5_B23 <= BS5_B3;
		end if;
	end if;
end process;
MAX_SEARCH_BS6A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS6_B0 > BS6_B1) then
			BS6_B01 <= BS6_B0;
		else
			BS6_B01 <= BS6_B1;
		end if;
		if(BS6_B2 > BS6_B3) then
			BS6_B23 <= BS6_B2;
		else
			BS6_B23 <= BS6_B3;
		end if;
	end if;
end process;
MAX_SEARCH_BS7A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS7_B0 > BS7_B1) then
			BS7_B01 <= BS7_B0;
		else
			BS7_B01 <= BS7_B1;
		end if;
		if(BS7_B2 > BS7_B3) then
			BS7_B23 <= BS7_B2;
		else
			BS7_B23 <= BS7_B3;
		end if;
	end if;
end process;
MAX_SEARCH_BS8A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS8_B0 > BS8_B1) then
			BS8_B01 <= BS8_B0;
		else
			BS8_B01 <= BS8_B1;
		end if;
		if(BS8_B2 > BS8_B3) then
			BS8_B23 <= BS8_B2;
		else
			BS8_B23 <= BS8_B3;
		end if;
	end if;
end process;
MAX_SEARCH_BS9A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS9_B0 > BS9_B1) then
			BS9_B01 <= BS9_B0;
		else
			BS9_B01 <= BS9_B1;
		end if;
		if(BS9_B2 > BS9_B3) then
			BS9_B23 <= BS9_B2;
		else
			BS9_B23 <= BS9_B3;
		end if;
	end if;
end process;
MAX_SEARCH_BS10A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS10_B0 > BS10_B1) then
			BS10_B01 <= BS10_B0;
		else
			BS10_B01 <= BS10_B1;
		end if;
		if(BS10_B2 > BS10_B3) then
			BS10_B23 <= BS10_B2;
		else
			BS10_B23 <= BS10_B3;
		end if;
	end if;
end process;
MAX_SEARCH_BS11A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS11_B0 > BS11_B1) then
			BS11_B01 <= BS11_B0;
		else
			BS11_B01 <= BS11_B1;
		end if;
		if(BS11_B2 > BS11_B3) then
			BS11_B23 <= BS11_B2;
		else
			BS11_B23 <= BS11_B3;
		end if;
	end if;
end process;
MAX_SEARCH_BS12A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS12_B0 > BS12_B1) then
			BS12_B01 <= BS12_B0;
		else
			BS12_B01 <= BS12_B1;
		end if;
		if(BS12_B2 > BS12_B3) then
			BS12_B23 <= BS12_B2;
		else
			BS12_B23 <= BS12_B3;
		end if;
	end if;
end process;
MAX_SEARCH_BS13A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS13_B0 > BS13_B1) then
			BS13_B01 <= BS13_B0;
		else
			BS13_B01 <= BS13_B1;
		end if;
		if(BS13_B2 > BS13_B3) then
			BS13_B23 <= BS13_B2;
		else
			BS13_B23 <= BS13_B3;
		end if;
	end if;
end process;
MAX_SEARCH_BS14A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS14_B0 > BS14_B1) then
			BS14_B01 <= BS14_B0;
		else
			BS14_B01 <= BS14_B1;
		end if;
		if(BS14_B2 > BS14_B3) then
			BS14_B23 <= BS14_B2;
		else
			BS14_B23 <= BS14_B3;
		end if;
	end if;
end process;
MAX_SEARCH_BS15A: process(CLK)
begin
	if rising_edge(CLK) then
		if(BS15_B0 > BS15_B1) then
			BS15_B01 <= BS15_B0;
		else
			BS15_B01 <= BS15_B1;
		end if;
		if(BS15_B2 > BS15_B3) then
			BS15_B23 <= BS15_B2;
		else
			BS15_B23 <= BS15_B3;
		end if;
	end if;
end process;


-- 1 CLK latency total
MAX_SEARCH_BS0B: process(BS0_B01, BS0_B23)
begin
		if(BS0_B01 > BS0_B23) then
			B_OUT0 <= std_logic_vector(BS0_B01);
		else
			B_OUT0 <= std_logic_vector(BS0_B23);
		end if;
end process;
MAX_SEARCH_BS1B: process(BS1_B01, BS1_B23)
begin
		if(BS1_B01 > BS1_B23) then
			B_OUT1 <= std_logic_vector(BS1_B01);
		else
			B_OUT1 <= std_logic_vector(BS1_B23);
		end if;
end process;
MAX_SEARCH_BS2B: process(BS2_B01, BS2_B23)
begin
		if(BS2_B01 > BS2_B23) then
			B_OUT2 <= std_logic_vector(BS2_B01);
		else
			B_OUT2 <= std_logic_vector(BS2_B23);
		end if;
end process;
MAX_SEARCH_BS3B: process(BS3_B01, BS3_B23)
begin
		if(BS3_B01 > BS3_B23) then
			B_OUT3 <= std_logic_vector(BS3_B01);
		else
			B_OUT3 <= std_logic_vector(BS3_B23);
		end if;
end process;
MAX_SEARCH_BS4B: process(BS4_B01, BS4_B23)
begin
		if(BS4_B01 > BS4_B23) then
			B_OUT4 <= std_logic_vector(BS4_B01);
		else
			B_OUT4 <= std_logic_vector(BS4_B23);
		end if;
end process;
MAX_SEARCH_BS5B: process(BS5_B01, BS5_B23)
begin
		if(BS5_B01 > BS5_B23) then
			B_OUT5 <= std_logic_vector(BS5_B01);
		else
			B_OUT5 <= std_logic_vector(BS5_B23);
		end if;
end process;
MAX_SEARCH_BS6B: process(BS6_B01, BS6_B23)
begin
		if(BS6_B01 > BS6_B23) then
			B_OUT6 <= std_logic_vector(BS6_B01);
		else
			B_OUT6 <= std_logic_vector(BS6_B23);
		end if;
end process;
MAX_SEARCH_BS7B: process(BS7_B01, BS7_B23)
begin
		if(BS7_B01 > BS7_B23) then
			B_OUT7 <= std_logic_vector(BS7_B01);
		else
			B_OUT7 <= std_logic_vector(BS7_B23);
		end if;
end process;
MAX_SEARCH_BS8B: process(BS8_B01, BS8_B23)
begin
		if(BS8_B01 > BS8_B23) then
			B_OUT8 <= std_logic_vector(BS8_B01);
		else
			B_OUT8 <= std_logic_vector(BS8_B23);
		end if;
end process;
MAX_SEARCH_BS9B: process(BS9_B01, BS9_B23)
begin
		if(BS9_B01 > BS9_B23) then
			B_OUT9 <= std_logic_vector(BS9_B01);
		else
			B_OUT9 <= std_logic_vector(BS9_B23);
		end if;
end process;
MAX_SEARCH_BS10B: process(BS10_B01, BS10_B23)
begin
		if(BS10_B01 > BS10_B23) then
			B_OUT10 <= std_logic_vector(BS10_B01);
		else
			B_OUT10 <= std_logic_vector(BS10_B23);
		end if;
end process;
MAX_SEARCH_BS11B: process(BS11_B01, BS11_B23)
begin
		if(BS11_B01 > BS11_B23) then
			B_OUT11 <= std_logic_vector(BS11_B01);
		else
			B_OUT11 <= std_logic_vector(BS11_B23);
		end if;
end process;
MAX_SEARCH_BS12B: process(BS12_B01, BS12_B23)
begin
		if(BS12_B01 > BS12_B23) then
			B_OUT12 <= std_logic_vector(BS12_B01);
		else
			B_OUT12 <= std_logic_vector(BS12_B23);
		end if;
end process;
MAX_SEARCH_BS13B: process(BS13_B01, BS13_B23)
begin
		if(BS13_B01 > BS13_B23) then
			B_OUT13 <= std_logic_vector(BS13_B01);
		else
			B_OUT13 <= std_logic_vector(BS13_B23);
		end if;
end process;
MAX_SEARCH_BS14B: process(BS14_B01, BS14_B23)
begin
		if(BS14_B01 > BS14_B23) then
			B_OUT14 <= std_logic_vector(BS14_B01);
		else
			B_OUT14 <= std_logic_vector(BS14_B23);
		end if;
end process;
MAX_SEARCH_BS15B: process(BS15_B01, BS15_B23)
begin
		if(BS15_B01 > BS15_B23) then
			B_OUT15 <= std_logic_vector(BS15_B01);
		else
			B_OUT15 <= std_logic_vector(BS15_B23);
		end if;
end process;
	

end Behavioral;

