SURF  1.0
SyncStatusVector.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : SyncStatusVector.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2014-04-11
5 -- Last update: 2014-06-02
6 -------------------------------------------------------------------------------
7 -- Description: General Purpose Status Vector and Status Counter module
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
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 : slv := "1"; -- 0 for active LOW, 1 for active HIGH (for statusIn port)
35  OUT_POLARITY_G : sl := '1'; -- 0 for active LOW, 1 for active HIGH (for irqOut port)
36  USE_DSP48_G : string := "no"; -- "no" for no DSP48 implementation, "yes" to use DSP48 slices
37  SYNTH_CNT_G : slv := "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 := 32; -- Counters' width
40  WIDTH_G : positive := 16); -- Status vector width
41  port (
42  ---------------------------------------------
43  -- Input Status bit Signals (wrClk domain)
44  ---------------------------------------------
45  statusIn : in slv(WIDTH_G-1 downto 0);-- Data to be 'synced'
46  ---------------------------------------------
47  -- Output Status bit Signals (rdClk domain)
48  ---------------------------------------------
49  statusOut : out slv(WIDTH_G-1 downto 0);-- Synced data
50  ---------------------------------------------
51  -- Status Bit Counters Signals (rdClk domain)
52  ---------------------------------------------
53  -- cntRstIn:
54  -- This input is the common resets all the counters
55  cntRstIn : in sl;
56  -- rollOverEnIn:
57  -- This input is counter roll over enable vector.
58  -- Each element of the vector corresponds to its respective counter.
59  -- For example: rollOverEnIn(0) is statusIn(0)'s counter roll over enable bit
60  -- rollOverEnIn(1) is statusIn(1)'s counter roll over enable bit
61  -- rollOverEnIn(2) is statusIn(2)'s counter roll over enable bit
62  -- .... and so on
63  rollOverEnIn : in slv(WIDTH_G-1 downto 0) := (others => '0'); -- No roll over for all counters by default
64  -- cntOut:
65  -- This output is counter value vector array.
66  -- The remapping of cntOut to a SLV array (outside of this module) is has followed:
67  --
68  -- for i in WIDTH_G-1 to 0 loop
69  -- for j in CNT_WIDTH_G-1 to 0 loop
70  -- MySlvArray(i)(j) <= cntOut(i, j);
71  -- end loop;
72  -- end loop;
73  --
74  cntOut : out SlVectorArray(WIDTH_G-1 downto 0, CNT_WIDTH_G-1 downto 0);
75  ---------------------------------------------
76  -- Interrupt Signals (rdClk domain)
77  ---------------------------------------------
78  -- irqEnIn:
79  -- This input is counter roll over enable vector.
80  -- Each element of the vector corresponds to its respective status bit.
81  -- For example: irqEnIn(0) is statusIn(0)'s enable interrupt bit
82  -- irqEnIn(1) is statusIn(1)'s enable interrupt bit
83  -- irqEnIn(2) is statusIn(2)'s enable interrupt bit
84  -- .... and so on
85  irqEnIn : in slv(WIDTH_G-1 downto 0) := (others => '0'); -- All bits disabled by default
86  -- irqOut:
87  -- This output is interrupt output signal.
88  irqOut : out sl;
89  ---------------------------------------------
90  -- Clocks and Reset Ports
91  ---------------------------------------------
92  wrClk : in sl;
93  wrRst : in sl := '0';
94  rdClk : in sl;
95  rdRst : in sl := '0');
96 end SyncStatusVector;
97 
98 architecture rtl of SyncStatusVector is
99 
100  type RegType is record
101  irqOut : sl;
102  hitVector : slv(WIDTH_G-1 downto 0);
103  end record RegType;
104 
105  constant REG_INIT_C : RegType := (
106  not(OUT_POLARITY_G),
107  (others => '0'));
108 
109  signal r : RegType := REG_INIT_C;
110  signal rin : RegType;
111 
112  signal statusStrobe : slv(WIDTH_G-1 downto 0);
113 
114 begin
115 
116  SyncVec_Inst : entity work.SynchronizerVector
117  generic map (
118  TPD_G => TPD_G,
121  WIDTH_G => WIDTH_G)
122  port map (
123  clk => rdClk,
124  dataIn => statusIn,
125  dataOut => statusOut);
126 
127  SyncOneShotCntVec_Inst : entity work.SynchronizerOneShotCntVector
128  generic map (
129  TPD_G => TPD_G,
135  OUT_POLARITY_G => "1",
140  WIDTH_G => WIDTH_G)
141  port map (
142  -- Write Ports (wrClk domain)
143  dataIn => statusIn,
144  -- Read Ports (rdClk domain)
146  cntRst => cntRstIn,
147  dataOut => statusStrobe,
148  cntOut => cntOut,
149  -- Clocks and Reset Ports
150  wrClk => wrClk,
151  wrRst => wrRst,
152  rdClk => rdClk,
153  rdRst => rdRst);
154 
155  comb : process (irqEnIn, r, rdRst, statusStrobe) is
156  variable i : integer;
157  variable v : RegType;
158  begin
159  -- Reset signals
160  v := REG_INIT_C;
161 
162  -- Refresh the mask check
163  for i in 0 to (WIDTH_G-1) loop
164  if irqEnIn(i) = '1' then
165  v.hitVector(i) := statusStrobe(i);
166  end if;
167  end loop;
168 
169  -- Check the hitVector vector for a new interrupt
170  if uOr(r.hitVector) = '1' then
171  v.irqOut := OUT_POLARITY_G;
172  end if;
173 
174  -- Sync Reset
175  if (RST_ASYNC_G = false and rdRst = RST_POLARITY_G) then
176  v := REG_INIT_C;
177  end if;
178 
179  -- Register the variable for next clock cycle
180  rin <= v;
181 
182  -- Outputs
183  irqOut <= r.irqOut;
184 
185  end process comb;
186 
187  seq : process (rdClk, rdRst) is
188  begin
189  if rising_edge(rdClk) then
190  r <= rin after TPD_G;
191  end if;
192  -- Async Reset
193  if (RST_ASYNC_G and rdRst = RST_POLARITY_G) then
194  r <= REG_INIT_C after TPD_G;
195  end if;
196  end process seq;
197 
198 end rtl;
std_logic sl
Definition: StdRtlPkg.vhd:28
BYPASS_SYNC_Gboolean := false
array(natural range <> ,natural range <> ) of sl SlVectorArray
Definition: StdRtlPkg.vhd:669
in rollOverEnslv( WIDTH_G- 1 downto 0)
WIDTH_Gpositive := 16
RST_ASYNC_Gboolean := false
COMMON_CLK_Gboolean := false
in dataInslv( WIDTH_G- 1 downto 0)
out cntOutSlVectorArray ( WIDTH_G- 1 downto 0, CNT_WIDTH_G- 1 downto 0)
USE_DSP48_Gstring := "no"
in dataInslv( WIDTH_G- 1 downto 0)
RELEASE_DELAY_Gpositive := 3
CNT_WIDTH_Gpositive := 32
in rollOverEnInslv( WIDTH_G- 1 downto 0) :=( others => '0')
in irqEnInslv( WIDTH_G- 1 downto 0) :=( others => '0')
out dataOutslv( WIDTH_G- 1 downto 0)
CNT_RST_EDGE_Gboolean := true
out statusOutslv( WIDTH_G- 1 downto 0)
out dataOutslv( WIDTH_G- 1 downto 0)
out cntOutSlVectorArray ( WIDTH_G- 1 downto 0, CNT_WIDTH_G- 1 downto 0)
std_logic_vector slv
Definition: StdRtlPkg.vhd:29
in statusInslv( WIDTH_G- 1 downto 0)