---------------------------------------------------------------------------------- -- Company: University of Connecticut -- Engineer: Igor Senderovich -- -- Create Date: 04:14:41 10/01/2007 -- Design Name: -- Module Name: Transmitter - behavioral -- Description: Assembles a packet D or S packet for transmission using -- the Transceiver. ---------------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; library FPGA_BasicComp; use FPGA_BasicComp.BasicComp.all; entity Transmitter is port ( Clk : in std_logic; Go : in std_logic; Done : out std_logic; LocStamp : in std_logic_vector (7 downto 0); PktType : in std_logic_vector (7 downto 0); RAM_EN : out std_logic; RAM_ADDR_tri : out std_logic_vector (9 downto 0); RAM_WE_tri : out std_logic_vector (1 downto 0); RAM_DI_tri : out std_logic_vector (15 downto 0); RAM_DO : in std_logic_vector (15 downto 0); TxRx_Go : out std_logic; TxRx_Rd_tri : out std_logic; TxRx_A_tri : out std_logic_vector (7 downto 0); TxRx_D_tri : out std_logic_vector (7 downto 0); TxRx_Q : in std_logic_vector (7 downto 0); TxRx_Done : in std_logic; INT_Go : out std_logic; INT_Mask_tri : out std_logic_vector (15 downto 0); INT_Found : in std_logic_vector (15 downto 0); INT_Done : in std_logic); --Ser_Go : out std_logic; --Ser_Done : in std_logic; --Ser_D_tri : out std_logic_vector (7 downto 0); --Debug : out std_logic); end Transmitter; architecture behavioral of Transmitter is component WriteDpacket is port ( Clk : in std_logic; Go : in std_logic; Done : out std_logic; LocStamp : in std_logic_vector (7 downto 0); RAM_EN : out std_logic; RAM_ADDR_tri : out std_logic_vector (9 downto 0); RAM_WE_tri : out std_logic_vector (1 downto 0); RAM_DI_tri : out std_logic_vector (15 downto 0); RAM_DO : in std_logic_vector (15 downto 0); TxRx_Go : out std_logic; TxRx_Rd_tri : out std_logic; TxRx_A_tri : out std_logic_vector (7 downto 0); TxRx_D_tri : out std_logic_vector (7 downto 0); TxRx_Q : in std_logic_vector (7 downto 0); TxRx_Done : in std_logic); end component; component WriteSpacket is port ( Clk : in std_logic; Go : in std_logic; Done : out std_logic; LocStamp : in std_logic_vector (7 downto 0); RAM_EN : out std_logic; RAM_ADDR_tri : out std_logic_vector (9 downto 0); RAM_WE_tri : out std_logic_vector (1 downto 0); RAM_DI_tri : out std_logic_vector (15 downto 0); RAM_DO : in std_logic_vector (15 downto 0); TxRx_Go : out std_logic; TxRx_Rd_tri : out std_logic; TxRx_A_tri : out std_logic_vector (7 downto 0); TxRx_D_tri : out std_logic_vector (7 downto 0); TxRx_Q : in std_logic_vector (7 downto 0); TxRx_Done : in std_logic); end component; type stage_t is (S0,S1,S2,S3,S4,S5,S6,S7,S8,S9,SA,SB); --,SS); signal stage : stage_t := S0; signal counter_4b : std_logic_vector (3 downto 0); signal Done_reg : std_logic := '0'; signal Go_WPD_reg : std_logic := '0'; signal Done_WPD : std_logic; signal Go_WPS_reg : std_logic := '0'; signal Done_WPS : std_logic; signal RAM_EN_WPD : std_logic; signal RAM_ADDR_WPD : std_logic_vector (9 downto 0); signal RAM_WE_WPD : std_logic_vector (1 downto 0); signal RAM_DI_WPD : std_logic_vector (15 downto 0); signal RAM_EN_WPS : std_logic; signal RAM_ADDR_WPS : std_logic_vector (9 downto 0); signal RAM_WE_WPS : std_logic_vector (1 downto 0); signal RAM_DI_WPS : std_logic_vector (15 downto 0); signal RAM_EN_reg : std_logic := '0'; signal RAM_ADDR_reg : std_logic_vector (9 downto 0) := (others => '0'); signal RAM_WE_reg : std_logic_vector (1 downto 0) := (others => '0'); signal RAM_DI_reg : std_logic_vector (15 downto 0) := (others => '0'); signal TxRx_Go_WPD : std_logic := '0'; signal TxRx_Rd_WPD : std_logic; signal TxRx_A_WPD : std_logic_vector (7 downto 0); signal TxRx_D_WPD : std_logic_vector (7 downto 0); signal TxRx_Go_WPS : std_logic := '0'; signal TxRx_Rd_WPS : std_logic; signal TxRx_A_WPS : std_logic_vector (7 downto 0); signal TxRx_D_WPS : std_logic_vector (7 downto 0); signal TxRx_Go_reg : std_logic := '0'; signal TxRx_Rd_reg : std_logic; signal TxRx_A_reg : std_logic_vector (7 downto 0) := (others => '0'); signal TxRx_D_reg : std_logic_vector (7 downto 0) := (others => '0'); signal INT_Go_reg : std_logic := '0'; signal INT_Mask_reg : std_logic_vector (15 downto 0) := (others => '0'); --signal Ser_Go_reg : std_logic := '0'; --signal Ser_D_reg : std_logic_vector (7 downto 0) := (others => '0'); --signal Debug_reg : std_logic := '0'; begin WriteDpacket_inst : WriteDpacket port map ( Clk => Clk, Go => Go_WPD_reg, Done => Done_WPD, LocStamp => LocStamp, RAM_EN => RAM_EN_WPD, RAM_ADDR_tri => RAM_ADDR_WPD, RAM_WE_tri => RAM_WE_WPD, RAM_DI_tri => RAM_DI_WPD, RAM_DO => RAM_DO, TxRx_Go => TxRx_Go_WPD, TxRx_Rd_tri => TxRx_Rd_WPD, TxRx_A_tri => TxRx_A_WPD, TxRx_D_tri => TxRx_D_WPD, TxRx_Q => TxRx_Q, TxRx_Done => TxRx_Done ); WriteSpacket_inst : WriteSpacket port map ( Clk => Clk, Go => Go_WPS_reg, Done => Done_WPS, LocStamp => LocStamp, RAM_EN => RAM_EN_WPS, RAM_ADDR_tri => RAM_ADDR_WPS, RAM_WE_tri => RAM_WE_WPS, RAM_DI_tri => RAM_DI_WPS, RAM_DO => RAM_DO, TxRx_Go => TxRx_Go_WPS, TxRx_Rd_tri => TxRx_Rd_WPS, TxRx_A_tri => TxRx_A_WPS, TxRx_D_tri => TxRx_D_WPS, TxRx_Q => TxRx_Q, TxRx_Done => TxRx_Done ); RAM_EN <= RAM_EN_WPD or RAM_EN_WPS or RAM_EN_reg; RAM_ADDR_tri <= RAM_ADDR_WPD when (RAM_EN_WPD = '1') else RAM_ADDR_WPS when (RAM_EN_WPS = '1') else RAM_ADDR_reg when (RAM_EN_reg = '1') else (others => 'Z'); RAM_WE_tri <= RAM_WE_WPD when (RAM_EN_WPD = '1') else RAM_WE_WPS when (RAM_EN_WPS = '1') else RAM_WE_reg when (RAM_EN_reg = '1') else (others => 'Z'); RAM_DI_tri <= RAM_DI_WPD when (RAM_EN_WPD = '1') else RAM_DI_WPS when (RAM_EN_WPS = '1') else RAM_DI_reg when (RAM_EN_reg = '1') else (others => 'Z'); TxRx_Go <= TxRx_Go_WPD or TxRx_Go_WPS or TxRx_Go_reg; TxRx_Rd_tri <= TxRx_Rd_WPD when (TxRx_Go_WPD = '1') else TxRx_Rd_WPS when (TxRx_Go_WPS = '1') else TxRx_Rd_reg when (TxRx_Go_reg = '1') else 'Z'; TxRx_A_tri <= TxRx_A_WPD when (TxRx_Go_WPD = '1') else TxRx_A_WPS when (TxRx_Go_WPS = '1') else TxRx_A_reg when (TxRx_Go_reg = '1') else (others => 'Z'); TxRx_D_tri <= TxRx_D_WPD when (TxRx_Go_WPD = '1') else TxRx_D_WPS when (TxRx_Go_WPS = '1') else TxRx_D_reg when (TxRx_Go_reg = '1') else (others => 'Z'); INT_Go <= INT_Go_reg; INT_Mask_tri <= INT_Mask_reg when (INT_Go_reg = '1') else (others => 'Z'); Sequencer : process (Clk) variable op_complete_var : std_logic; begin if rising_edge(Clk) then stage <= stage; Done_reg <= '0'; counter_4b <= (others => '0'); -- disable the RAM lines when not in use RAM_EN_reg <= '0'; RAM_ADDR_reg <= (others => '0'); RAM_WE_reg <= (others => '0'); RAM_DI_reg <= (others => '0'); -- disable the MuxIntel bus when not in use TxRx_Go_reg <= '0'; TxRx_Rd_reg <= '0'; TxRx_A_reg <= (others => '0'); TxRx_D_reg <= (others => '0'); -- disable the interrupt control lines when not in use INT_Go_reg <= '0'; INT_Mask_reg <= (others => '0'); -- disable the serial port when not in use --Ser_Go_reg <= '0'; --Ser_D_reg <= (others => '0'); --Debug_reg <= '0'; op_complete_var := TxRx_Go_reg and TxRx_Done; case stage is when S0 => if (Go = '1') then stage <= S1; end if; ------------------------------------------- -- Put TXSTARTH (0x59) and TXSTARTL (0x5A) -- at 0x0000 location in Tx buffer. ------------------------------------------- when S1 => TxRx_A_reg <= X"59"; TxRx_D_reg <= X"00"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S2; end if; when S2 => TxRx_A_reg <= X"5A"; TxRx_D_reg <= X"00"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S3; end if; ------------------------------------------------------- -- Copy the destination and source ethernet addresses -- into the transmit buffer using the random access -- method by writing RAMADDRH:RAMADDRL and RAMTXDATA. ------------------------------------------------------- when S3 => counter_4b <= counter_4b; RAM_ADDR_reg <= "0000010" & counter_4b(3 downto 1); TxRx_A_reg <= X"08"; TxRx_D_reg <= X"00"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S4; end if; when S4 => counter_4b <= counter_4b; RAM_EN_reg <= '1'; RAM_ADDR_reg <= RAM_ADDR_reg; TxRx_A_reg <= X"09"; TxRx_D_reg <= X"0" & counter_4b; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S5; end if; when S5 => counter_4b <= counter_4b; RAM_EN_reg <= '1'; RAM_ADDR_reg <= RAM_ADDR_reg; -- RAM_DO is valid at the first clock in S5 because the -- RAM_ADDR and RAM_EN lines were set up in S3 and S4. TxRx_A_reg <= X"04"; if (counter_4b(0) = '0') then TxRx_D_reg <= RAM_DO(15 downto 8); else TxRx_D_reg <= RAM_DO(7 downto 0); end if; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then counter_4b <= counter_4b + 1; if (counter_4b = X"b") then stage <= S6; else stage <= S3; end if; end if; ------------------------------------------------------- -- Packet payload depends on the type of packet being -- sent, either type S or type D. Delegate the rest -- of the packet formatting to the packet writers. ------------------------------------------------------- when S6 => if (PktType = X"53") then Go_WPS_reg <= not Done_WPS; op_complete_var := Go_WPS_reg and Done_WPS; else Go_WPD_reg <= not Done_WPD; op_complete_var := Go_WPD_reg and Done_WPD; end if; if (op_complete_var = '1') then stage <= S7; end if; ------------------------------------------- -- Put TXSTARTH (0x59) and TXSTARTL (0x5A) -- back at 0x0000 location again. ------------------------------------------- when S7 => TxRx_A_reg <= X"59"; TxRx_D_reg <= X"00"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S8; end if; when S8 => TxRx_A_reg <= X"5A"; TxRx_D_reg <= X"00"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S9; end if; ----------------------- -- Send the packet! ----------------------- when S9 => TxRx_A_reg <= X"53"; TxRx_D_reg <= X"01"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= SA; end if; when SA => INT_Mask_reg <= X"0004"; INT_Go_reg <= not INT_Done; op_complete_var := INT_Go_reg and INT_Done; if (op_complete_var = '1') then stage <= SB; end if; ----------------------------------------- -- Send a status byte to the serial port ----------------------------------------- -- when SS => -- Ser_D_reg <= PktType; -- Ser_Go_reg <= not Ser_Done; -- op_complete_var := Ser_Go_reg and Ser_Done; -- if (op_complete_var = '1') then -- stage <= SB; -- end if; when SB => if (Go = '1') then Done_reg <= '1'; else stage <= S0; end if; end case; else stage <= stage; Done_reg <= Done_reg; counter_4b <= counter_4b; RAM_EN_reg <= RAM_EN_reg; RAM_ADDR_reg <= RAM_ADDR_reg; RAM_WE_reg <= RAM_WE_reg; RAM_DI_reg <= RAM_DI_reg; TxRx_Go_reg <= TxRx_Go_reg; TxRx_Rd_reg <= TxRx_Rd_reg; TxRx_A_reg <= TxRx_A_reg; TxRx_D_reg <= TxRx_D_reg; INT_Go_reg <= INT_Go_reg; INT_Mask_reg <= INT_Mask_reg; --Ser_Go_reg <= Ser_Go_reg; --Ser_D_reg <= Ser_D_reg; --Debug_reg <= Debug_reg; end if; end process; --Ser_Go <= Ser_Go_reg; --Ser_D_tri <= Ser_D_reg when (Ser_Go_reg = '1') else (others => 'Z'); --Debug <= Debug_reg; Done <= Done_reg; end behavioral;