SURF  1.0
SyncTrigRate.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : SyncTrigRate.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2014-04-16
5 -- Last update: 2017-01-26
6 -------------------------------------------------------------------------------
7 -- Description: This module measures the trigger rate of a trigger
8 -------------------------------------------------------------------------------
9 -- This file is part of 'SLAC Firmware Standard Library'.
10 -- It is subject to the license terms in the LICENSE.txt file found in the
11 -- top-level directory of this distribution and at:
12 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
13 -- No part of 'SLAC Firmware Standard Library', including this file,
14 -- may be copied, modified, propagated, or distributed except according to
15 -- the terms contained in the LICENSE.txt file.
16 -------------------------------------------------------------------------------
17 
18 library ieee;
19 use ieee.std_logic_1164.all;
20 use ieee.std_logic_unsigned.all;
21 use ieee.std_logic_arith.all;
22 
23 use work.StdRtlPkg.all;
24 
25 --! @see entity
26  --! @ingroup base_sync
27 entity SyncTrigRate is
28  generic (
29  TPD_G : time := 1 ns; -- Simulation FF output delay
30  COMMON_CLK_G : boolean := false; -- true if locClk & refClk are the same clock
31  ONE_SHOT_G : boolean := false;
32  IN_POLARITY_G : sl := '1'; -- 0 for active LOW, 1 for active HIGH
33  REF_CLK_FREQ_G : real := 200.0E+6; -- units of Hz
34  REFRESH_RATE_G : real := 1.0E+0; -- units of Hz
35  USE_DSP48_G : string := "no"; -- "no" for no DSP48 implementation, "yes" to use DSP48 slices
36  CNT_WIDTH_G : positive := 32); -- Counters' width
37  port (
38  -- Trigger Input (locClk domain)
39  trigIn : in sl;
40  -- Trigger Rate Output (locClk domain)
42  trigRateOut : out slv(CNT_WIDTH_G-1 downto 0); -- units of REFRESH_RATE_G
43  trigRateOutMax : out slv(CNT_WIDTH_G-1 downto 0); -- units of REFRESH_RATE_G
44  trigRateOutMin : out slv(CNT_WIDTH_G-1 downto 0); -- units of REFRESH_RATE_G
45  -- Clocks
46  locClkEn : in sl := '1';
47  locClk : in sl;
48  locRst : in sl := '1';
49  refClk : in sl;
50  refRst : in sl := '0');
51 end SyncTrigRate;
52 
53 architecture rtl of SyncTrigRate is
54 
55  constant TIMEOUT_C : natural := getTimeRatio(REF_CLK_FREQ_G, REFRESH_RATE_G)-1;
56 
57  type RegType is record
58  armed : sl;
59  updated : sl;
60  updateStat : sl;
61  timer : natural range 0 to TIMEOUT_C;
62  trigCntDly : slv(CNT_WIDTH_G-1 downto 0);
63  rate : slv(CNT_WIDTH_G-1 downto 0);
64  rateMax : slv(CNT_WIDTH_G-1 downto 0);
65  rateMin : slv(CNT_WIDTH_G-1 downto 0);
66  end record;
67 
68  constant REG_INIT_C : RegType := (
69  armed => '0',
70  updated => '0',
71  updateStat => '0',
72  timer => 0,
73  trigCntDly => (others => '0'),
74  rate => (others => '0'),
75  rateMax => (others => '0'),
76  rateMin => (others => '0'));
77 
78  signal r : RegType := REG_INIT_C;
79  signal rin : RegType;
80 
81  signal trig : sl := not(IN_POLARITY_G);
82  signal updated : sl := '0';
83  signal trigCnt : slv(CNT_WIDTH_G-1 downto 0) := (others => '0');
84  signal trigCntSync : slv(CNT_WIDTH_G-1 downto 0) := (others => '0');
85 
86 begin
87 
88  BYPASS_ONE_SHOT : if (ONE_SHOT_G = false) generate
89 
90  trig <= trigIn;
91 
92  end generate;
93 
94  GEN_ONE_SHOT : if (ONE_SHOT_G = true) generate
95 
96  U_OneShot : entity work.SynchronizerOneShot
97  generic map (
98  TPD_G => TPD_G,
101  port map (
102  clk => locClk,
103  dataIn => trigIn,
104  dataOut => trig);
105 
106  end generate;
107 
108  process (locClk) is
109  begin
110  if rising_edge(locClk) then
111  -- Check the clock enable
112  if (locClkEn = '1') or (ONE_SHOT_G = true) then
113  -- Check for a trigger
114  if (trig = IN_POLARITY_G) then
115  -- Increment the counter
116  trigCnt <= trigCnt + 1 after TPD_G;
117  end if;
118  end if;
119  end if;
120  end process;
121 
122  SyncIn_trigCnt : entity work.SynchronizerFifo
123  generic map (
124  TPD_G => TPD_G,
127  port map (
128  wr_clk => locClk,
129  din => trigCnt,
130  rd_clk => refClk,
131  dout => trigCntSync);
132 
133  comb : process (r, refRst, trigCntSync) is
134  variable v : RegType;
135  begin
136  -- Latch the current value
137  v := r;
138 
139  -- Reset strobing signals
140  v.updated := '0';
141  v.updateStat := '0';
142 
143  -- Check for timeout
144  if r.timer = TIMEOUT_C then
145  -- Reset the timer
146  v.timer := 0;
147  -- Update the rate measurement
148  v.updated := '1';
149  v.rate := trigCntSync - r.trigCntDly;
150  -- Keep a delayed copy of trigCntSync
151  v.trigCntDly := trigCntSync;
152  else
153  -- Increment the timer
154  v.timer := r.timer + 1;
155  end if;
156 
157  -- Check for update previous clock cycle
158  if (r.updated = '1') then
159  -- Set the flag
160  v.updateStat := '1';
161  -- Check if first time after reset
162  if (r.armed = '0') then
163  -- Set the flag
164  v.armed := '1';
165  -- Pass the current values to the statistics measurements
166  v.rateMax := r.rate;
167  v.rateMin := r.rate;
168  else
169  -- Compare for max. value
170  if (r.rate > r.rateMax) then
171  -- Update the statistics measurement
172  v.rateMax := r.rate;
173  end if;
174  -- Compare for min. value
175  if (r.rate < r.rateMin) then
176  -- Update the statistics measurement
177  v.rateMin := r.rate;
178  end if;
179  end if;
180  end if;
181 
182  -- Reset
183  if refRst = '1' then
184  -- Re-arm and reset statistics measurements only
185  v.armed := '0';
186  v.rateMax := r.rate;
187  v.rateMin := r.rate;
188  end if;
189 
190  -- Register the variable for next clock cycle
191  rin <= v;
192 
193  end process comb;
194 
195  seq : process (refClk) is
196  begin
197  if rising_edge(refClk) then
198  r <= rin after TPD_G;
199  end if;
200  end process seq;
201 
202  SyncOut_rate : entity work.SynchronizerFifo
203  generic map (
204  TPD_G => TPD_G,
207  port map (
208  wr_clk => refClk,
209  wr_en => r.updated,
210  din => r.rate,
211  rd_clk => locClk,
213  dout => trigRateOut);
214 
215  SyncOut_rateMax : entity work.SynchronizerFifo
216  generic map (
217  TPD_G => TPD_G,
220  port map (
221  wr_clk => refClk,
222  wr_en => r.updateStat,
223  din => r.rateMax,
224  rd_clk => locClk,
225  dout => trigRateOutMax);
226 
227  SyncOut_rateMin : entity work.SynchronizerFifo
228  generic map (
229  TPD_G => TPD_G,
232  port map (
233  wr_clk => refClk,
234  wr_en => r.updateStat,
235  din => r.rateMin,
236  rd_clk => locClk,
237  dout => trigRateOutMin);
238 
239 end rtl;
IN_POLARITY_Gsl := '1'
out trigRateUpdatedsl
std_logic sl
Definition: StdRtlPkg.vhd:28
in dinslv( DATA_WIDTH_G- 1 downto 0)
out doutslv( DATA_WIDTH_G- 1 downto 0)
REFRESH_RATE_Greal := 1.0E+0
_library_ ieeeieee
COMMON_CLK_Gboolean := false
COMMON_CLK_Gboolean := false
in locClkEnsl := '1'
in refRstsl := '0'
out trigRateOutMinslv( CNT_WIDTH_G- 1 downto 0)
CNT_WIDTH_Gpositive := 32
ONE_SHOT_Gboolean := false
TPD_Gtime := 1 ns
out trigRateOutMaxslv( CNT_WIDTH_G- 1 downto 0)
USE_DSP48_Gstring := "no"
REF_CLK_FREQ_Greal := 200.0E+6
out trigRateOutslv( CNT_WIDTH_G- 1 downto 0)
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
std_logic_vector slv
Definition: StdRtlPkg.vhd:29