---------------------------------------------------------------------------------- -- Company: University of Connecticut -- Engineer: Igor Senderovich -- -- Create Date: 22:52:57 11/29/2007 -- Design Name: -- Module Name: ResetHard - behavioral -- Description: Performs cold reboot of the Ethernet Controller using its /RST -- pin and carries out initial configuration. It also resets the -- DAC to its power-on state. ---------------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; library FPGA_BasicComp; use FPGA_BasicComp.BasicComp.all; use FPGA_BasicComp.FPGA_config.all; entity ResetHard is port ( Clk : in std_logic; Go : in std_logic; Done : out std_logic; Eth_Rst_low : inout std_logic; Eth_INT_low : in std_logic; DAC_Rst : out std_logic; -- RAM block access lines 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); -- MuxIntel parallel bus lines TxRx_Go : out std_logic; TxRx_Done : in std_logic; TxRx_A_tri : out std_logic_vector (7 downto 0); TxRx_D_tri : out std_logic_vector (7 downto 0); TxRx_Rd_tri : out std_logic; TxRx_Q : in std_logic_vector (7 downto 0); -- Ethernet interrupt control lines 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); -- Serial port --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 ResetHard; architecture behavioral of ResetHard is component MACaddrLoad is Port ( Clk : in std_logic; Go : in std_logic; Done : out std_logic; -- RAM block access lines 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); -- MuxIntel parallel bus lines TxRx_Go : out std_logic; TxRx_Done : in std_logic; TxRx_A_tri : out std_logic_vector (7 downto 0); TxRx_D_tri : out std_logic_vector (7 downto 0); TxRx_Rd_tri : out std_logic; TxRx_Q : in std_logic_vector (7 downto 0)); end component; type stage_t is (S00, S01, S02, S03, S04, S05, S06, S07, S08, S09, S0A, S0B, S0C, S0D, S0E, S0F, S10, S11, S12, S13, S14, S15, S16, S17, S18, S19, S1A); --,SS); signal stage : stage_t := S00; signal counter_2b : std_logic_vector (1 downto 0); signal counter_32b : std_logic_vector (31 downto 0); signal MACcfg : std_logic_vector (7 downto 0); signal Done_reg : std_logic := '0'; signal Eth_Rst_reg : std_logic := '0'; signal DAC_Rst_reg : std_logic := '0'; signal TxRx_Go_reg : std_logic := '0'; 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 TxRx_Rd_reg : std_logic := '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'; signal Go_MAC : std_logic := '0'; signal Done_MAC : std_logic; signal TxRx_Go_MAC : std_logic := '0'; signal TxRx_A_MAC : std_logic_vector (7 downto 0); signal TxRx_D_MAC : std_logic_vector (7 downto 0); signal TxRx_Rd_MAC : std_logic; begin -- Component that loads the MAC address registers MACaddrLoad_inst : MACaddrLoad port map ( Clk => Clk, Go => Go_MAC, Done => Done_MAC, -- RAM block access lines RAM_EN => RAM_EN, RAM_ADDR_tri => RAM_ADDR_tri, RAM_WE_tri => RAM_WE_tri, RAM_DI_tri => RAM_DI_tri, RAM_DO => RAM_DO, -- MuxIntel parallel bus lines TxRx_Go => TxRx_Go_MAC, TxRx_Done => TxRx_Done, TxRx_A_tri => TxRx_A_MAC, TxRx_D_tri => TxRx_D_MAC, TxRx_Rd_tri => TxRx_Rd_MAC, TxRx_Q => TxRx_Q ); TxRx_Go <= TxRx_Go_MAC or TxRx_Go_reg; TxRx_A_tri <= TxRx_A_MAC when (TxRx_Go_MAC = '1') else TxRx_A_reg when (TxRx_Go_reg = '1') else (others => 'Z'); TxRx_D_tri <= TxRx_D_MAC when (TxRx_Go_MAC = '1') else TxRx_D_reg when (TxRx_Go_reg = '1') else (others => 'Z'); TxRx_Rd_tri <= TxRx_Rd_MAC when (TxRx_Go_MAC = '1') else TxRx_Rd_reg when (TxRx_Go_reg = '1') else 'Z'; INT_Go <= INT_Go_reg; INT_Mask_tri <= INT_Mask_reg when (INT_Go_reg = '1') else (others => 'Z'); Eth_Rst_low <= '0' when (Eth_Rst_reg = '1') else 'Z'; DAC_Rst <= DAC_Rst_reg; ResetSequence : process (Clk) variable AutoNegFailed_var : std_logic; variable op_complete_var : std_logic; variable more2do_var : std_logic; begin if rising_edge(Clk) then stage <= stage; counter_2b <= (others => '0'); counter_32b <= (others => '0'); Done_reg <= '0'; -- disable the MuxIntel 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 when not in use INT_Go_reg <= '0'; INT_Mask_reg <= (others => '0'); -- disable the ethernet controller reset Eth_Rst_reg <= '0'; -- disable the DAC reset DAC_Rst_reg <= '0'; -- disable the serial port when not in use --Ser_Go_reg <= '0'; --Ser_D_reg <= (others => '0'); --Debug_reg <= Debug_reg; op_complete_var := TxRx_Go_reg and TxRx_Done; case stage is when S00 => if (Go = '1') then stage <= S01; end if; ---------------------------------------------- --(1) Hold Eth's /RST pin low for 512 cycles, -- more than the req. 15e-6 sec @ 20MHz. -- Also send the reset signal to the DAC. ---------------------------------------------- when S01 => DAC_Rst_reg <= '1'; Eth_Rst_reg <= '1'; counter_32b <= counter_32b + 1; op_complete_var := counter_32b(9) or dbShort; if (op_complete_var = '1') then stage <= S02; end if; ----------------------------------------- --(2) Wait for the Eth's /RST pin to rise ----------------------------------------- when S02 => if (Eth_Rst_low = '1') then stage <= S03; end if; ----------------------------------------- --(3) Wait for oscillator initialization ----------------------------------------- when S03 => op_complete_var := not Eth_INT_low; if (op_complete_var = '1') then stage <= S04; end if; ----------------------------------------- --(4) Wait for self initialization ----------------------------------------- when S04 => INT_Mask_reg <= X"0020"; INT_Go_reg <= not INT_Done; op_complete_var := INT_Go_reg and INT_Done; if (op_complete_var = '1') then stage <= S05; end if; ------------------------------------------ --(5) Disable unnecessary interrupts -- leaving only the following enabled: -- * self initialized -- * oscillator initialized -- * receive FIFO full -- * packet received -- * autonegotiation failed -- * autonegotiation complete ------------------------------------------ when S05 => TxRx_A_reg <= X"64"; TxRx_D_reg <= "00110011"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S06; end if; when S06 => TxRx_A_reg <= X"7d"; TxRx_D_reg <= "00000101"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S07; end if; ------------------------------------- --(6) Initialize the physical layer -- * disable PhyEN in PHYCN -- * enable AutoNeg -- * enable SMSQ, -- * enable LinkInteg -- * enable JabberDetect -- * enable AutoPolCorr -- * enable AdPause -- * disable transmitter powersave mode -- * re-enable PhyEN in PHYCN -- * enable full duplex (ignored due to autoneg) -- * wait 1.5ms for physical layer to initialize -- * enable Tx, Rx -- * wait for autonegotiation ------------------------------------- when S07 => TxRx_A_reg <= X"78"; TxRx_D_reg <= "00000000"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S08; end if; when S08 => TxRx_A_reg <= X"79"; TxRx_D_reg <= "11110110"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S09; end if; when S09 => TxRx_A_reg <= X"7A"; TxRx_D_reg <= "10000000"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S0A; end if; when S0A => TxRx_A_reg <= X"78"; TxRx_D_reg <= "10010000"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S0B; end if; when S0B => counter_32b <= counter_32b + 1; op_complete_var := counter_32b(15) or dbShort; if (op_complete_var = '1') then stage <= S0C; end if; when S0C => TxRx_A_reg <= X"78"; TxRx_D_reg <= "11110000"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S0D; end if; when S0D => INT_Mask_reg <= X"070a"; INT_Go_reg <= not INT_Done; AutoNegFailed_var := INT_Found(10); counter_32b <= counter_32b + 1; op_complete_var := INT_Go_reg and INT_Done; if (counter_32b(26) = '1') then stage <= S01; elsif (op_complete_var = '1') then if (AutoNegFailed_var = '1') then stage <= S01; else stage <= S0E; end if; end if; -------------------------------------------------- --(7) Enable LED and unnecessary reset sources -- * disable software reset -- * disable power failure detection reset -- * enable LEDs and keep internal weak -- pull-ups (0x70(1)=0) enabled -------------------------------------------------- when S0E => TxRx_A_reg <= X"72"; TxRx_D_reg <= "00000000"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S0F; end if; when S0F => TxRx_A_reg <= X"70"; TxRx_D_reg <= "00000100"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S10; end if; --------------------------------------------------- --(8) Initialization of the MAC -- * determine whether the physical layer is -- in half or full duplex: MACCfg(4) carries -- duplex info (Full='1') -- * write 0x40B3 (full-duplex) or 0x4012 -- (half-duplex) to MACCF -- * write 0x0015 (full-duplex) or 0x0012 -- (half-duplex) to IPGT -- * configure IPGR to manual's recommendation -- * load MAC address from flash memory -- * enable reception ---------------------------------------------------- when S10 => TxRx_A_reg <= X"78"; TxRx_Rd_reg <= '1'; TxRx_Go_reg <= not TxRx_Done; MACcfg <= TxRx_Q; if (op_complete_var = '1') then stage <= S11; end if; when S11 => counter_2b <= counter_2b; case counter_2b is when "00" => TxRx_A_reg <= X"0A"; TxRx_D_reg <= X"01"; when "01" => TxRx_A_reg <= X"0B"; TxRx_D_reg <= X"40"; when "10" => TxRx_A_reg <= X"0C"; TxRx_D_reg <= MACcfg(4) & '0' & MACcfg(4) & "1001" & MACcfg(4); when others => TxRx_A_reg <= X"0D"; TxRx_D_reg <= X"00"; end case; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then counter_2b <= counter_2b + 1; if (counter_2b = "11") then stage <= S12; end if; end if; when S12 => counter_2b <= counter_2b; case counter_2b is when "00" => TxRx_A_reg <= X"0A"; TxRx_D_reg <= X"02"; when "01" => TxRx_A_reg <= X"0B"; TxRx_D_reg <= X"00"; when "10" => TxRx_A_reg <= X"0C"; TxRx_D_reg <= "00010" & MACcfg(4) & not MACcfg(4) & MACcfg(4); when others => TxRx_A_reg <= X"0D"; TxRx_D_reg <= X"00"; end case; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then counter_2b <= counter_2b + 1; if (counter_2b = "11") then stage <= S13; end if; end if; when S13 => counter_2b <= counter_2b; case counter_2b is when "00" => TxRx_A_reg <= X"0A"; TxRx_D_reg <= X"03"; when "01" => TxRx_A_reg <= X"0B"; TxRx_D_reg <= X"0C"; when "10" => TxRx_A_reg <= X"0C"; TxRx_D_reg <= X"12"; when others => TxRx_A_reg <= X"0D"; TxRx_D_reg <= X"00"; end case; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then counter_2b <= counter_2b + 1; if (counter_2b = "11") then stage <= S14; end if; end if; when S14 => counter_2b <= counter_2b; case counter_2b is when "00" => TxRx_A_reg <= X"0A"; TxRx_D_reg <= X"05"; when "01" => TxRx_A_reg <= X"0B"; TxRx_D_reg <= X"05"; when "10" => TxRx_A_reg <= X"0C"; TxRx_D_reg <= X"EE"; when others => TxRx_A_reg <= X"0D"; TxRx_D_reg <= X"00"; end case; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then counter_2b <= counter_2b + 1; if (counter_2b = "11") then stage <= S15; end if; end if; when S15 => Go_MAC <= not Done_MAC; op_complete_var := Go_MAC and Done_MAC; if (op_complete_var = '1') then stage <= S16; end if; when S16 => counter_2b <= counter_2b; case counter_2b is when "00" => TxRx_A_reg <= X"0A"; TxRx_D_reg <= X"00"; when "01" => TxRx_A_reg <= X"0B"; TxRx_D_reg <= X"00"; when "10" => TxRx_A_reg <= X"0C"; TxRx_D_reg <= X"09"; when others => TxRx_A_reg <= X"0D"; TxRx_D_reg <= X"00"; end case; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then counter_2b <= counter_2b + 1; if (counter_2b = "11") then stage <= S17; end if; end if; ------------------------------------------------------------ --(8) Initialize the receive buffer, filter, and hash table -- * configure RXFILT (0x10) to accept broadcast -- and multicast packets but no runts -- * configure the hash table to accept all packets ------------------------------------------------------------ when S17 => TxRx_A_reg <= X"10"; TxRx_D_reg <= X"08"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S18; end if; when S18 => TxRx_A_reg <= X"0E"; TxRx_D_reg <= X"FF"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S19; end if; when S19 => TxRx_A_reg <= X"0F"; TxRx_D_reg <= X"FF"; TxRx_Rd_reg <= '0'; TxRx_Go_reg <= not TxRx_Done; if (op_complete_var = '1') then stage <= S1A; end if; ------------------------------------------------------------ -- Send a serial port message indicating completion status ------------------------------------------------------------ -- when SS => -- Ser_Go_reg <= not Ser_Done; -- Ser_D_reg <= X"3" & "0001"; -- op_complete_var := Ser_Go_reg and Ser_Done; -- if (op_complete_var = '1') then -- stage <= S1A; -- end if; when S1A => if (Go = '1') then Done_reg <= '1'; else stage <= S00; end if; end case; else stage <= stage; counter_2b <= counter_2b; counter_32b <= counter_32b; MACcfg <= MACcfg; TxRx_Go_reg <= TxRx_Go_reg; TxRx_A_reg <= TxRx_A_reg; TxRx_D_reg <= TxRx_D_reg; TxRx_Rd_reg <= TxRx_Rd_reg; INT_Go_reg <= INT_Go_reg; INT_Mask_reg <= INT_Mask_reg; Eth_Rst_reg <= Eth_Rst_reg; DAC_Rst_reg <= DAC_Rst_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;