1 |
2 |
boa_a_m |
-------------------------------------------------------------
|
2 |
|
|
-- Filename: RESET_TIMER.VHD
|
3 |
|
|
-- Version: 1
|
4 |
|
|
-- Date last modified: 1-28-11
|
5 |
|
|
-- Inheritance: n/a
|
6 |
|
|
--
|
7 |
|
|
-- description:
|
8 |
|
|
-- 1. Generate a long (>10ms) negative RESET_N pulse at power up or after a RESET_START trigger.
|
9 |
|
|
-- The timer to define the length of the RESET_N pulse is set at the time of HDL synthesis
|
10 |
|
|
-- (see the constants within)
|
11 |
|
|
-- 2. Generate a short INITIAL_CONFIG_PULSE, 50ms after the RESET_N deassertion
|
12 |
|
|
-- to start configuring the PHY over the MDIO interface.
|
13 |
|
|
-- Beware: as the PHY may turn off its 125 MHz while RESET_N is being asserted, one should
|
14 |
|
|
-- not rely on the availability of this 125 MHz clock to generate RESET_N (circular logic).
|
15 |
|
|
---------------------------------------------------------------
|
16 |
|
|
library IEEE;
|
17 |
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
18 |
|
|
use IEEE.STD_LOGIC_ARITH.ALL;
|
19 |
|
|
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
20 |
|
|
|
21 |
|
|
entity RESET_TIMER is
|
22 |
|
|
generic (
|
23 |
|
|
CLK_FREQUENCY: integer := 120
|
24 |
|
|
-- CLK frequency in MHz. Needed to compute actual delays.
|
25 |
|
|
);
|
26 |
|
|
Port (
|
27 |
|
|
--// CLK
|
28 |
|
|
CLK: in std_logic;
|
29 |
|
|
-- GLOBAL CLOCK, always available, even during PHY reset. Used as time reference.
|
30 |
|
|
|
31 |
|
|
RESET_START: in std_logic;
|
32 |
|
|
-- 1-CLK pulse trigger to reset PHY IC and set the strapping options.
|
33 |
|
|
-- This trigger is optional. This component will automatically generate a RESET_N
|
34 |
|
|
-- long negative pulse at power up. Synchronous with CLK.
|
35 |
|
|
RESET_COMPLETE: out std_logic;
|
36 |
|
|
-- '1' to indicate the end of this reset transaction. '1' while transaction is in progress.
|
37 |
|
|
-- synchronous with CLK
|
38 |
|
|
|
39 |
|
|
--// OUTPUTS
|
40 |
|
|
INITIAL_CONFIG_PULSE: out std_logic;
|
41 |
|
|
-- 1-clk pulse to trigger the first-time PHY configuration over the MDIO interface.
|
42 |
|
|
-- synchronous with CLK
|
43 |
|
|
|
44 |
|
|
RESET_N: out std_logic
|
45 |
|
|
-- PHY INTERFACE. long negative pulse at power up or after a RESET_START.
|
46 |
|
|
-- hardware pin configurations are strapped-in at the de-assertion (rising edge)
|
47 |
|
|
-- of RESET_N. > 10ms long.
|
48 |
|
|
-- synchronous with CLK
|
49 |
|
|
|
50 |
|
|
|
51 |
|
|
);
|
52 |
|
|
end entity;
|
53 |
|
|
|
54 |
|
|
architecture Behavioral of RESET_TIMER is
|
55 |
|
|
--------------------------------------------------------
|
56 |
|
|
-- SIGNALS
|
57 |
|
|
--------------------------------------------------------
|
58 |
|
|
signal STATE: integer range 0 to 3 := 0;
|
59 |
|
|
signal TIMER1: std_logic_vector(23 downto 0) := x"000000";
|
60 |
|
|
constant TIMER1_VAL: integer := (CLK_FREQUENCY * 10000) -1;
|
61 |
|
|
-- the objective is to generate a 10ms min RESET_N pulse. Adjust TIMER1_VAL as needed.
|
62 |
|
|
-- Example: CLK = 125 MHz clock. The resulting TIMER1_VAL is 10E-2 * 125E6 -1
|
63 |
|
|
signal TIMER2: std_logic_vector(23 downto 0) := x"000000";
|
64 |
|
|
constant TIMER2_VAL: integer := (CLK_FREQUENCY * 50000) -1;
|
65 |
|
|
-- Example: 100uS at 125MHz = 12499
|
66 |
|
|
|
67 |
|
|
signal RESET_STARTED: std_logic := '0';
|
68 |
|
|
signal POWER_UP: std_logic := '0';
|
69 |
|
|
|
70 |
|
|
|
71 |
|
|
--------------------------------------------------------
|
72 |
|
|
-- IMPLEMENTATION
|
73 |
|
|
--------------------------------------------------------
|
74 |
|
|
begin
|
75 |
|
|
|
76 |
|
|
RESET_N_GEN_001: process(CLK)
|
77 |
|
|
begin
|
78 |
|
|
if rising_edge(CLK) then
|
79 |
|
|
if(RESET_START = '1') or (POWER_UP = '0') then
|
80 |
|
|
-- initialize timer upon powerup or RESET_START
|
81 |
|
|
POWER_UP <= '1';
|
82 |
|
|
INITIAL_CONFIG_PULSE <= '0';
|
83 |
|
|
TIMER1 <= (others => '0');
|
84 |
|
|
TIMER2 <= (others => '0');
|
85 |
|
|
STATE <= 1;
|
86 |
|
|
elsif(STATE = 1) then
|
87 |
|
|
if (TIMER1 < TIMER1_VAL) then
|
88 |
|
|
-- count until TIMER1_VAL (timer expired)
|
89 |
|
|
TIMER1 <= TIMER1 + 1;
|
90 |
|
|
else
|
91 |
|
|
-- timer1 expired
|
92 |
|
|
STATE <= 2;
|
93 |
|
|
end if;
|
94 |
|
|
elsif(STATE = 2) then
|
95 |
|
|
if (TIMER2 < TIMER2_VAL) then
|
96 |
|
|
-- count until TIMER2_VAL (timer expired)
|
97 |
|
|
TIMER2 <= TIMER2 + 1;
|
98 |
|
|
else
|
99 |
|
|
-- timer2 expired
|
100 |
|
|
STATE <= 3;
|
101 |
|
|
INITIAL_CONFIG_PULSE <= '1';
|
102 |
|
|
end if;
|
103 |
|
|
elsif(STATE = 3) then
|
104 |
|
|
INITIAL_CONFIG_PULSE <= '0';
|
105 |
|
|
end if;
|
106 |
|
|
end if;
|
107 |
|
|
end process;
|
108 |
|
|
|
109 |
|
|
RESET_COMPLETE <= '1' when (STATE = 3) else '0';
|
110 |
|
|
|
111 |
|
|
|
112 |
|
|
--// OUTPUTS ----------------------
|
113 |
|
|
RESET_N <= '0' when (STATE = 0) or (STATE = 1) else '1'; -- active low reset
|
114 |
|
|
|
115 |
|
|
end Behavioral;
|
116 |
|
|
|