1 ------------------------------------------------------------------------------- 2 -- File : SyncClockFreq.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2014-04-17 5 -- Last update: 2014-04-17 6 ------------------------------------------------------------------------------- 7 -- Description: This module measures the frequency of an input clock 8 -- with respect to a stable reference clock. 9 ------------------------------------------------------------------------------- 10 -- This file is part of 'SLAC Firmware Standard Library'. 11 -- It is subject to the license terms in the LICENSE.txt file found in the 12 -- top-level directory of this distribution and at: 13 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 14 -- No part of 'SLAC Firmware Standard Library', including this file, 15 -- may be copied, modified, propagated, or distributed except according to 16 -- the terms contained in the LICENSE.txt file. 17 ------------------------------------------------------------------------------- 20 use ieee.std_logic_1164.
all;
21 use ieee.std_logic_unsigned.
all;
22 use ieee.std_logic_arith.
all;
27 --! @ingroup base_sync 30 TPD_G : := 1 ns;
-- Simulation FF output delay 31 USE_DSP48_G : := "no";
-- "no" for no DSP48 implementation, "yes" to use DSP48 slices 38 -- Frequency Measurement and Monitoring Outputs (locClk domain) 41 locked :
out sl; -- '1' CLK_LOWER_LIMIT_G < clkIn < CLK_UPPER_LIMIT_G
42 tooFast : out sl;
-- '1' when clkIn > CLK_UPPER_LIMIT_G 43 tooSlow : out sl;
-- '1' when clkIn < CLK_LOWER_LIMIT_G 46 locClk :
in sl; -- System clock
53 constant CLK_LOWER_LIMIT_C : := getTimeRatio(CLK_LOWER_LIMIT_G, 1.
0E+0);
-- lower limit 54 constant CLK_UPPER_LIMIT_C : := getTimeRatio(CLK_UPPER_LIMIT_G, 1.
0E+0);
-- upper limit 73 attribute use_dsp48 : ;
74 attribute use_dsp48 of cntIn : signal is USE_DSP48_G;
75 attribute use_dsp48 of cntStable : signal is USE_DSP48_G;
76 attribute use_dsp48 of cntAccum : signal is USE_DSP48_G;
77 attribute use_dsp48 of accum : signal is USE_DSP48_G;
78 attribute use_dsp48 of diffCnt : signal is USE_DSP48_G;
79 attribute use_dsp48 of freqHertz : signal is USE_DSP48_G;
89 --------------------------- 90 -- Free Running Counter 91 --------------------------- 94 if rising_edge(clkIn) then 95 -- Increment the counter 96 cntIn <= cntIn + 1 after TPD_G;
100 ------------------------------------------------ 101 -- Calculate the frequency of the input clock 102 ------------------------------------------------ 108 --Write Ports (wr_clk domain) 111 --Read Ports (rd_clk domain) 117 if rising_edge(refClk) then 119 wrEn <= '0' after TPD_G;
120 -- Increment the Counter 121 cntStable <= cntStable + 1 after TPD_G;
122 -- Check if we have reached the targeted refresh rate 123 if cntStable = REFRESH_MAX_CNT_C then 125 cntStable <= (others => '0') after TPD_G;
126 cntAccum <= (others => '0') after TPD_G;
127 accum <= (others => '0') after TPD_G;
128 -- Calculate the new frequency 129 diffCnt <= (cntOut - cntOutDly) after TPD_G;
130 -- Save the current count value for next refresh cycle 131 cntOutDly <= cntOut after TPD_G;
132 -- Reset the done flag 133 doneAccum <= '0' after TPD_G;
134 -- Check if we are accumulating 135 elsif doneAccum = '0' then 136 -- Check for accumulation counter 138 -- Write the accumulated value to the output FIFO 139 wrEn <= '1' after TPD_G;
141 doneAccum <= '1' after TPD_G;
143 -- Increment the counter 144 cntAccum <= cntAccum + 1 after TPD_G;
145 -- Accumulate the value 146 accum <= accum + diffCnt after TPD_G;
157 --Write Ports (wr_clk domain) 161 --Read Ports (rd_clk domain) 166 --------------------------- 167 -- Clock Monitoring Process 168 --------------------------- 171 if rising_edge(locClk) then 172 -- Update locked flag 173 if (tooFastDet = '0') and (tooSlowDet = '0') then 174 lockedDet <= '1'
after TPD_G;
176 lockedDet <= '0'
after TPD_G;
178 -- Check for too fast input clock 179 if freqHertz > CLK_UPPER_LIMIT_C then 180 tooFastDet <= '1' after TPD_G;
182 tooFastDet <= '0' after TPD_G;
184 -- Check for too slow input clock 185 if freqHertz < CLK_LOWER_LIMIT_C then 186 tooSlowDet <= '1' after TPD_G;
188 tooSlowDet <= '0' after TPD_G;
USE_DSP48_Gstring := "no"
in dinslv( DATA_WIDTH_G- 1 downto 0)
REF_CLK_FREQ_Greal := 200.0E+6
CNT_WIDTH_Gpositive := 32
out doutslv( DATA_WIDTH_G- 1 downto 0)
out freqOutslv( CNT_WIDTH_G- 1 downto 0)
REFRESH_RATE_Greal := 1.0E+3
CLK_LOWER_LIMIT_Greal := 159.0E+6
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
CLK_UPPER_LIMIT_Greal := 161.0E+6