ZCU_Start/non-modules/clkreset.vhd

125 lines
4.4 KiB
VHDL
Raw Normal View History

2024-01-06 02:42:53 +00:00
--------------------------------------------------------------------------
-- File : clkreset.vhd
----------------------------------------------------------------------------
-- Description : Wrapper for clock PLL and reset logic
--
-- External 'p_reset' input resets the PLL immediately and sets the 'reset'
-- active high to the internal FPGA logic.
-- When the reset goes inactive the PLL will try to generate the requested
-- output freq clock 'clk_i' for the FPGA internal logic from the 'p_clk' input.
-- Once the PLL output clock is stable the PLL sets the 'pll_locked' output high.
-- A counter then increments to 255 and then the 'reset' output is set low
-- to allow the FPGA logic to run.
--
-- *** Check p_reset_n polarity, design assumes active low ***
--
----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity clkreset is
port(
-- Reset and clock from pads
p_reset : in std_logic; -- From RESET input pad
p_clk_n : in std_logic; -- From CLOCK input pad, N
p_clk_p : in std_logic; -- From CLOCK input pad, P
-- Reset and clock outputs to all internal logic
clk : out std_logic;
lock : out std_logic;
reset : out std_logic
);
end clkreset;
------------------------------------------------------------------------
-- Structural architecture instantiates a vendor IP block clock tile.
------------------------------------------------------------------------
architecture struct of clkreset is
signal pll_locked : std_logic;
signal pll_locked_d1 : std_logic := '0';
signal clk_i : std_logic;
signal cnt_reset : unsigned(7 downto 0) := X"00";
signal reset_pll : std_logic;
-- Clock generator IP. Use MMCM or PLL
-- component clkpll
-- port (
-- refclk : in std_logic := '0'; -- refclk.clk
-- reset : in std_logic := '0'; -- reset.reset
-- outclk_0 : out std_logic; -- outclk0.clk
-- locked : out std_logic -- locked.export
-- );
-- end component;
component clk_wiz_0
port (-- Clock in ports
-- Clock out ports
outclk_0 : out std_logic;
-- Status and control signals
reset : in std_logic;
locked : out std_logic;
clk_in1_p : in std_logic; -- refclk, P
clk_in1_n : in std_logic -- refclk, N
);
end component;
begin
clk <= clk_i;
lock <= pll_locked_d1;
reset_pll <= p_reset;
---------------------------------------------------------------------------------
-- Clock generator. 100 MHz clock from XX MHz board clock input
---------------------------------------------------------------------------------
-- u_clkpll : clkpll
-- port map(
-- refclk => p_clk , -- in std_logic := '0'; -- refclk.clk
-- reset => reset_pll , -- in std_logic := '0'; -- reset.reset
-- outclk_0 => clk_i , -- out std_logic; -- outclk0.clk
-- locked => pll_locked -- out std_logic -- locked.export
-- );
u_clkpll : clk_wiz_0
port map (
-- Clock out ports
outclk_0 => clk_i, -- out
-- Status and control signals
reset => reset_pll, -- in
locked => pll_locked, -- out
-- Clock in ports
clk_in1_p => p_clk_p, -- in
clk_in1_n => p_clk_n -- in
);
-------------------------------------------------------------------------------
-- Keep main logic reset until PLL locked for 255 clock cycles
-------------------------------------------------------------------------------
pr_reset : process (p_reset, pll_locked, clk_i)
begin
if (p_reset = '1' or pll_locked = '0') then
reset <= '1';
pll_locked_d1 <= '0';
cnt_reset <= X"00";
elsif rising_edge(clk_i) then
pll_locked_d1 <= pll_locked;
if (pll_locked_d1 = '1' and cnt_reset < X"FF") then
cnt_reset <= cnt_reset + 1;
end if;
if (cnt_reset < X"FF") then
reset <= '1';
else
reset <= '0';
end if;
end if;
end process;
end struct;