---------------------------------------------------------
--  TRANSMITTER VHDL 
--  File: transmitter.vhd
--  SYNOPSYS DESIGN CONTEST 2001
--  Tom Wada / Univ. of the Ryukyus 2000/9
---------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all, IEEE.NUMERIC_STD.all;

entity TRANSMITTER is
    port( CLK     :  in  std_logic;
	  RESET   :  in  std_logic;
	  TXOUT   :  out unsigned(1 downto 0);
	  SYNCOUT :  out std_logic );
end entity TRANSMITTER;

architecture RTL of  TRANSMITTER is
    signal  counter : unsigned(6 downto 0);   -- 127 state counter
    signal  state   : unsigned(2 downto 0);   -- 8 state counter
    signal  pn1     : unsigned(6 downto 0);   -- pn code 1
    signal  pn2     : unsigned(6 downto 0);   -- pn code 2
    signal  pn3     : unsigned(6 downto 0);   -- pn code 3
    signal  data    : unsigned(2 downto 0);   -- data(0) for pn1
                                              -- data(1) for pn2
					      -- data(2) for pn3

begin

--  127 state counter & 8 state counter 
    FSM: process(CLK,RESET)
    begin
	if (RESET='1') then
	    counter <= (others => '0');
	    state   <= "000";
        elsif rising_edge(CLK) then
	    if (counter = "1111110") then
		counter <= (others => '0');
		state   <= state +1;
            else
		counter <= counter + 1;
            end if;
        end if;
    end process FSM;

--  PN code generator --
    PN_GEN: process(CLK,RESET)
    begin
	if (RESET='1') then
	    pn1 <= (others => '1');
	    pn2 <= (others => '1');
	    pn3 <= (others => '1');
        elsif rising_edge(CLK) then
	    pn1(6 downto 1) <= pn1(5 downto 0);
	    pn1(0) <= pn1(6) xor pn1(2);
	    
	    pn2(6 downto 1) <= pn2(5 downto 0);
	    pn2(0) <= pn2(6) xor pn2(2) xor pn2(1) xor pn2(0);

	    pn3(6 downto 1) <= pn3(5 downto 0);
	    pn3(0) <= pn3(6) xor pn3(3) xor pn3(2) xor pn3(1);
        end if;
    end process PN_GEN;

-- Data generator 
    DATA_GEN: process(state)
    begin
        case state is
	    when "000" => data <= "000";
	    when "001" => data <= "001";
	    when "010" => data <= "010";
	    when "011" => data <= "011";
	    when "100" => data <= "100";
	    when "101" => data <= "101";
	    when "110" => data <= "110";
	    when "111" => data <= "111";
	    when others=> data <= "XXX";
        end case;
    end process DATA_GEN;

--  TXOUT generator
    TXOUT_GEN: process(CLK,RESET)
    begin
	if (RESET='1') then
	    TXOUT   <= "00";
	    SYNCOUT <= '0';
        elsif rising_edge(CLK) then
            TXOUT <= ('0' & (pn1(6) xor data(0)))
	           + ('0' & (pn2(6) xor data(1)))
	           + ('0' & (pn3(6) xor data(2)));
            if(counter = "0000000") then
		SYNCOUT <= '1';
            else
		SYNCOUT <= '0';
            end if;
        end if;
    end process TXOUT_GEN;

end architecture RTL;
