SURF  1.0
SynchronizerOneShotCnt.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : SynchronizerOneShotCnt.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2014-04-11
5 -- Last update: 2014-04-14
6 -------------------------------------------------------------------------------
7 -- Description: Wrapper for SynchronizerOneShot with counter output
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_arith.all;
21 use ieee.std_logic_unsigned.all;
22 
23 use work.StdRtlPkg.all;
24 
25 --! @see entity
26  --! @ingroup base_sync
28  generic (
29  TPD_G : time := 1 ns; -- Simulation FF output delay
30  RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset
31  RST_ASYNC_G : boolean := false;-- true if reset is asynchronous, false if reset is synchronous
32  COMMON_CLK_G : boolean := false;-- True if wrClk and rdClk are the same clock
33  RELEASE_DELAY_G : positive := 3; -- Delay between deassertion of async and sync resets
34  IN_POLARITY_G : sl := '1'; -- 0 for active LOW, 1 for active HIGH (dataIn port)
35  OUT_POLARITY_G : sl := '1'; -- 0 for active LOW, 1 for active HIGH (dataOut port)
36  USE_DSP48_G : string := "no"; -- "no" for no DSP48 implementation, "yes" to use DSP48 slices
37  SYNTH_CNT_G : sl := '1'; -- Set to 1 for synthesising counter RTL, '0' to not synthesis the counter
38  CNT_RST_EDGE_G : boolean := true; -- true if counter reset should be edge detected, else level detected
39  CNT_WIDTH_G : positive := 16);
40  port (
41  -- Write Ports (wrClk domain)
42  dataIn : in sl; -- trigger to be sync'd
43  -- Read Ports (rdClk domain)
44  rollOverEn : in sl; -- '1' allows roll over of the counter
45  cntRst : in sl := not RST_POLARITY_G; -- Optional counter reset
46  dataOut : out sl; -- synced one-shot pulse
47  cntOut : out slv(CNT_WIDTH_G-1 downto 0);-- synced counter
48  -- Clocks and Reset Ports
49  wrClk : in sl;
50  wrRst : in sl := not RST_POLARITY_G;
51  rdClk : in sl; -- clock to be SYNC'd to
52  rdRst : in sl := not RST_POLARITY_G);
53 begin
54 
55 end SynchronizerOneShotCnt;
56 
57 architecture rtl of SynchronizerOneShotCnt is
58 
59  constant MAX_CNT_C : slv(CNT_WIDTH_G-1 downto 0) := (others => '1');
60 
61  type RegType is record
62  dataInDly : sl;
63  cntOut : slv(CNT_WIDTH_G-1 downto 0);
64  end record RegType;
65  constant REG_INIT_C : RegType := (
66  not(IN_POLARITY_G),
67  (others => '0'));
68  signal r : RegType := REG_INIT_C;
69  signal rin : RegType;
70  signal syncRst,
71  cntRstSync,
72  rollOverEnSync : sl;
73  signal cntOutSync : slv(CNT_WIDTH_G-1 downto 0);
74 
75  -- Attribute for XST
76  attribute use_dsp48 : string;
77  attribute use_dsp48 of r : signal is USE_DSP48_G;
78 
79 begin
80 
81  SyncOneShot_0 : entity work.SynchronizerOneShot
82  generic map (
83  TPD_G => TPD_G,
90  port map (
91  clk => rdClk,
92  rst => rdRst,
93  dataIn => dataIn,
94  dataOut => dataOut);
95 
96  CNT_RST_EDGE : if (CNT_RST_EDGE_G = true) generate
97 
98  SyncOneShot_1 : entity work.SynchronizerOneShot
99  generic map (
100  TPD_G => TPD_G,
107  port map (
108  clk => wrClk,
109  rst => wrRst,
110  dataIn => cntRst,
111  dataOut => cntRstSync);
112 
113  end generate;
114 
115  CNT_RST_LEVEL : if (CNT_RST_EDGE_G = false) generate
116 
117  Synchronizer_0 : entity work.Synchronizer
118  generic map (
119  TPD_G => TPD_G,
121  OUT_POLARITY_G => '1',
124  STAGES_G => (RELEASE_DELAY_G-1))
125  port map (
126  clk => wrClk,
127  rst => wrRst,
128  dataIn => cntRst,
129  dataOut => cntRstSync);
130 
131  end generate;
132 
133  Synchronizer_1 : entity work.Synchronizer
134  generic map (
135  TPD_G => TPD_G,
137  OUT_POLARITY_G => '1',
140  STAGES_G => (RELEASE_DELAY_G-1))
141  port map (
142  clk => wrClk,
143  rst => wrRst,
144  dataIn => rollOverEn,
145  dataOut => rollOverEnSync);
146 
147  BYPASS_CNT : if (SYNTH_CNT_G = '0') generate
148 
149  cntOut <= (others => '0');
150 
151  end generate;
152 
153  GEN_CNT : if (SYNTH_CNT_G = '1') generate
154 
155  comb : process (cntRstSync, dataIn, r, rollOverEnSync, wrRst) is
156  variable v : RegType;
157  begin
158  -- Latch the current value
159  v := r;
160 
161  -- Keep a record of the last syncData
162  v.dataInDly := dataIn;
163 
164  -- Active HIGH logic
165  if IN_POLARITY_G = '1' then
166  -- Check for a rising edge
167  if (dataIn = '1') and (r.dataInDly = '0') then
168  -- Check for counter roll over
169  if (rollOverEnSync = '1') or (r.cntOut /= MAX_CNT_C) then
170  -- Increment the counter
171  v.cntOut := r.cntOut + 1;
172  end if;
173  end if;
174  -- Active LOW logic
175  else
176  -- Check for a falling edge
177  if (dataIn = '0') and (r.dataInDly = '1') then
178  -- Check for counter roll over
179  if (rollOverEnSync = '1') or (r.cntOut /= MAX_CNT_C) then
180  -- Increment the counter
181  v.cntOut := r.cntOut + 1;
182  end if;
183  end if;
184  end if;
185 
186  -- Check for a counter reset
187  if cntRstSync = RST_POLARITY_G then
188  v.cntOut := (others => '0');
189  end if;
190 
191  -- Sync Reset
192  if (RST_ASYNC_G = false and wrRst = RST_POLARITY_G) then
193  v.cntOut := (others => '0');
194  v.dataInDly := dataIn; -- prevent accidental edge detection
195  end if;
196 
197  -- Register the variable for next clock cycle
198  rin <= v;
199 
200  -- Outputs
201  cntOutSync <= r.cntOut;
202 
203  end process comb;
204 
205  seq : process (dataIn, wrClk, wrRst) is
206  begin
207  if rising_edge(wrClk) then
208  r <= rin after TPD_G;
209  end if;
210  -- Async Reset
211  if (RST_ASYNC_G and wrRst = RST_POLARITY_G) then
212  r <= REG_INIT_C after TPD_G;
213  r.dataInDly <= dataIn after TPD_G; -- prevent accidental edge detection
214  end if;
215  end process seq;
216 
217  SyncFifo_Inst : entity work.SynchronizerFifo
218  generic map (
219  TPD_G => TPD_G,
223  port map (
224  -- Asynchronous Reset
225  rst => wrRst,
226  --Write Ports (wr_clk domain)
227  wr_clk => wrClk,
228  din => cntOutSync,
229  --Read Ports (rd_clk domain)
230  rd_clk => rdClk,
231  dout => cntOut);
232 
233  end generate;
234 
235 end architecture rtl;
std_logic sl
Definition: StdRtlPkg.vhd:28
in rstsl :=not RST_POLARITY_G
in dinslv( DATA_WIDTH_G- 1 downto 0)
BYPASS_SYNC_Gboolean := false
STAGES_Gpositive := 2
RST_POLARITY_Gsl := '1'
out dataOutsl
out doutslv( DATA_WIDTH_G- 1 downto 0)
out cntOutslv( CNT_WIDTH_G- 1 downto 0)
RST_ASYNC_Gboolean := false
in rstsl :=not RST_POLARITY_G
COMMON_CLK_Gboolean := false
BYPASS_SYNC_Gboolean := false
TPD_Gtime := 1 ns
SYNC_STAGES_Ginteger range 3 to ( 2** 24):= 3
OUT_POLARITY_Gsl := '1'
in wrRstsl :=not RST_POLARITY_G
in cntRstsl :=not RST_POLARITY_G
RST_ASYNC_Gboolean := false
in rdRstsl :=not RST_POLARITY_G
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
std_logic_vector slv
Definition: StdRtlPkg.vhd:29