-------------------------------------------------
--	Simple Bit Error Rate Tester (max count of 2^24-1)
--	list5-1.vhd
-------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;

entity BERT is
	port( RESET : in std_logic;
		CLK : in std_logic; 
		TCK : in std_logic;
		RCK : in std_logic;
		RcvBit : in std_logic;
		RefBit : in std_logic;
		MesSw : in std_logic;
		Sel : in std_logic_vector(2 downto 0);
		Dout : out std_logic_vector(7 downto 0);
		TxD : out std_logic_vector(14 downto 0)
	);
end BERT;

architecture RTL of BERT is 

signal PRBS_reg : std_logic_vector(14 downto 0);
signal BitCounter : std_logic_vector(23 downto 0);
signal ErrCounter : std_logic_vector(23 downto 0);
signal TckDelay1, TckDelay2 : std_logic;
signal RckDelay1, RckDelay2 : std_logic;
signal RcvBitSample, RcvBitSync, RefBitSync : std_logic;
signal Measure : std_logic;

begin


TxD <= PRBS_reg;

-- PRBS
	process (CLK, RESET) begin
		if (RESET = '0') then
			PRBS_reg <= "111111111111111";
		elsif (CLK'event and CLK='1') then
                        --if (TckDelay1 = '1' and TckDelay2 = '0') then 
				-- Polynomial X(n) = x15 + x1 + 1, PN15
				PRBS_reg(14) <= PRBS_reg(0) xor PRBS_reg(1);
				for I in 0 to 13 loop
					PRBS_reg(I) <= PRBS_reg(I+1);
				end loop;
			--end if;
		end if;
	end process;


-- TCK, RCK
--	process (CLK, RESET) begin
--		if (RESET = '0') then
--			TckDelay1 <= '0';
--			TckDelay2 <= '0';
--			RckDelay1 <= '0';
--			RckDelay2 <= '0';
--		elsif (CLK'event and CLK='1') then
--			TckDelay1 <= TCK;
--			TckDelay2 <= TckDelay1;
--			RckDelay1 <= RCK;
--			RckDelay2 <= RckDelay1;
--		end if;
--	end process;


-- RcvBit
	process (RCK, RESET) begin
		if (RESET = '0') then
			RcvBitSample <= '0';
		elsif (RCK'event and RCK='1') then
			RcvBitSample <= RcvBit;
		end if;
	end process;


-- RcvBit, RefBit, MesSw
	process (CLK, RESET) begin
		if (RESET = '0') then
			RcvBitSync <= '0';
			RefBitSync <= '0';
			Measure <= '0';
		elsif (CLK'event and CLK='1') then
			RcvBitSync <= RcvBitSample;
			RefBitSync <= RefBit;
			Measure <= MesSw;
		end if;
	end process;


--
	process (CLK, RESET) begin
		if (RESET = '0') then
			BitCounter <= x"000000";
		elsif (CLK'event and CLK='1') then
			--if (RckDelay1 = '1' and RckDelay2 = '0' and Measure = '1') then
			if (Measure = '1') then
				BitCounter <= BitCounter + 1;
			end if;
		end if;
	end process;

--
	process (CLK, RESET) begin
		if (RESET = '0') then
			ErrCounter <= x"000000";
		elsif (CLK'event and CLK='1') then
			--if (RckDelay1 = '1' and RckDelay2 = '0' and Measure = '1') then
			if (Measure = '1') then
				if (RcvBitSync /= RefBitSync ) then
					ErrCounter <= ErrCounter + 1;
				end if;
			end if;
		end if;
	end process;

	process(Sel, BitCounter, ErrCounter) begin
		-- Sel
		case Sel is
			when "000" =>
				Dout <= BitCounter(7 downto 0);
			when "001" =>
				Dout <= BitCounter(15 downto 8);
			when "010"|"011" =>
				Dout <= BitCounter(23 downto 16);
			when "100" =>
				Dout <= ErrCounter(7 downto 0);
			when "101" =>
				Dout <= ErrCounter(15 downto 8);
			when others => -- "110"|"111"
				Dout <= ErrCounter(23 downto 16);
		end case;
	end process;

end RTL;