-------------------------------------------------------------
-- Filename:  NRZ1.VHD
-- Authors: 
--		Alain Zarembowitch / MSS
-- Version: 0
-- Last modified: 3/2/16

-- Inheritance: 	N/A
--
-- description:  converts between NRZ-L, -M and -S
-- Maximum speed 1 bit/CLK
-- Latency 1 CLK
---------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity NRZ1 is
    Port ( 
	    CLK   : in  std_logic;
	    SYNC_RESET   : in  std_logic;

	    -- Serial input
		 DATA_IN: in std_logic;
		 DATA_VALID_IN: in std_logic;
		 
		 -- Controls
		 CONTROL: in std_logic_vector(2 downto 0);
			-- 0 bypassed
			-- 1 NRZ-L to NRZ-M
			-- 2 NRZ-L to NRZ-S
			-- 3 NRZ-M to NRZ-L
			-- 4 NRZ-S to NRZ-L
		 
	    -- Serial output
		 DATA_OUT: out std_logic;
		 DATA_VALID_OUT: out std_logic
	 
		);
end entity;

architecture Behavioral of NRZ1 is
--------------------------------------------------------
--     SIGNALS
--------------------------------------------------------
signal DATA_IN_D: std_logic := '0';
signal DATA_VALID_IN_D: std_logic := '0';
signal DATA_OUT_local: std_logic := '0';
signal DATA_VALID_OUT_local: std_logic := '0';
--------------------------------------------------------
--      IMPLEMENTATION
--------------------------------------------------------
begin

RECLOCK_001: process(CLK)
begin
	if rising_edge(CLK) then
		-- remember the last input bit
		if(SYNC_RESET = '1') then
			DATA_IN_D <= '0';
		elsif(DATA_VALID_IN = '1') then
			DATA_IN_D <= DATA_IN;
		end if;
	end if;
end process;

PROCESS_001: process(CLK)
begin
	if rising_edge(CLK) then
		DATA_VALID_OUT_local <= DATA_VALID_IN;
		
		if(SYNC_RESET = '1') then
			DATA_OUT_local <= '0';
		elsif(DATA_VALID_IN = '1') then
			if(unsigned(CONTROL) = 0) then
				-- bypass mode
				DATA_OUT_local <= DATA_IN;
			elsif(unsigned(CONTROL) = 1) then
				-- NRZ-L to NRZ-M
				-- 1 causes a transition
				if(DATA_IN = '1') then
					DATA_OUT_local <= not  DATA_OUT_local;
				end if;
			elsif(unsigned(CONTROL) = 2) then
				-- NRZ-L to NRZ-S
				-- 0 causes a transition
				if(DATA_IN = '0') then
					DATA_OUT_local <= not  DATA_OUT_local;
				end if;
			elsif(unsigned(CONTROL) = 3) then
				-- NRZ-M to NRZ-L
				if(DATA_IN /= DATA_IN_D) then
					DATA_OUT_local <= '1';
				else
					DATA_OUT_local <= '0';
				end if;
			elsif(unsigned(CONTROL) = 4) then
				-- NRZ-S to NRZ-L
				if(DATA_IN /= DATA_IN_D) then
					DATA_OUT_local <= '0';
				else
					DATA_OUT_local <= '1';
				end if;
			end if;
		end if;
	end if;
end process;

DATA_VALID_OUT <= DATA_VALID_OUT_local;
DATA_OUT <= DATA_OUT_local;

end Behavioral;
