SURF  1.0
AxiStreamMon.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiStreamMon.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2016-07-14
5 -- Last update: 2017-01-26
6 -------------------------------------------------------------------------------
7 -- Description: AXI Stream Monitor 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_arith.all;
21 use ieee.std_logic_unsigned.all;
22 
23 use work.StdRtlPkg.all;
24 use work.AxiStreamPkg.all;
25 
26 --! @see entity
27  --! @ingroup axi
28 entity AxiStreamMon is
29  generic (
30  TPD_G : time := 1 ns;
31  COMMON_CLK_G : boolean := false; -- true if axisClk = statusClk
32  AXIS_CLK_FREQ_G : real := 156.25E+6; -- units of Hz
34  port (
35  -- AXIS Stream Interface
36  axisClk : in sl;
37  axisRst : in sl;
40  -- Status Interface
41  statusClk : in sl;
42  statusRst : in sl;
43  frameRate : out slv(31 downto 0); -- units of Hz
44  frameRateMax : out slv(31 downto 0); -- units of Hz
45  frameRateMin : out slv(31 downto 0); -- units of Hz
46  bandwidth : out slv(63 downto 0); -- units of Byte/s
47  bandwidthMax : out slv(63 downto 0); -- units of Byte/s
48  bandwidthMin : out slv(63 downto 0)); -- units of Byte/s
49 end AxiStreamMon;
50 
51 architecture rtl of AxiStreamMon is
52 
53  constant TKEEP_C : natural := AXIS_CONFIG_G.TDATA_BYTES_C;
54  constant TIMEOUT_C : natural := getTimeRatio(AXIS_CLK_FREQ_G, 1.0)-1;
55 
56  type RegType is record
57  armed : sl;
58  frameSent : sl;
59  tValid : sl;
60  tKeep : slv(15 downto 0);
61  updated : sl;
62  updateStat : sl;
63  timer : natural range 0 to TIMEOUT_C;
64  accum : slv(39 downto 0);
65  bandwidth : slv(39 downto 0);
66  bandwidthMax : slv(39 downto 0);
67  bandwidthMin : slv(39 downto 0);
68  end record;
69 
70  constant REG_INIT_C : RegType := (
71  armed => '0',
72  frameSent => '0',
73  tValid => '0',
74  tKeep => (others => '0'),
75  updated => '0',
76  updateStat => '0',
77  timer => 0,
78  accum => (others => '0'),
79  bandwidth => (others => '0'),
80  bandwidthMax => (others => '0'),
81  bandwidthMin => (others => '0'));
82 
83  signal r : RegType := REG_INIT_C;
84  signal rin : RegType;
85 
86  signal bw : slv(39 downto 0);
87  signal bwMax : slv(39 downto 0);
88  signal bwMin : slv(39 downto 0);
89 
90  -- attribute dont_touch : string;
91  -- attribute dont_touch of r : signal is "true";
92 
93 begin
94 
95  U_packetRate : entity work.SyncTrigRate
96  generic map (
97  TPD_G => TPD_G,
99  REF_CLK_FREQ_G => AXIS_CLK_FREQ_G, -- units of Hz
100  REFRESH_RATE_G => 1.0, -- units of Hz
101  CNT_WIDTH_G => 32) -- Counters' width
102  port map (
103  -- Trigger Input (locClk domain)
104  trigIn => r.frameSent,
105  -- Trigger Rate Output (locClk domain)
109  -- Clocks
110  locClk => statusClk,
111  locRst => statusRst,
112  refClk => axisClk,
113  refRst => axisRst);
114 
115  comb : process (axisMaster, axisRst, axisSlave, r) is
116  variable v : RegType;
117  begin
118  -- Latch the current value
119  v := r;
120 
121  -- Reset strobing signals
122  v.tValid := '0';
123  v.updated := '0';
124  v.updateStat := '0';
125 
126  -- Check for end of frame
127  v.frameSent := axisMaster.tValid and axisMaster.tLast and axisSlave.tReady;
128 
129  -- Check for data moving
130  if (axisMaster.tValid = '1') and (axisSlave.tReady = '1') then
131  -- Set the flag
132  v.tValid := '1';
133  -- Sample the tKeep
134  v.tKeep(TKEEP_C-1 downto 0) := axisMaster.tKeep(TKEEP_C-1 downto 0);
135  end if;
136 
137  -- Check if last cycle had data moving
138  if r.tValid = '1' then
139  -- Update the accumulator
140  v.accum := r.accum + getTKeep(r.tKeep);
141  end if;
142 
143  -- Increment the timer
144  v.timer := r.timer + 1;
145 
146  -- Check for timeout
147  if r.timer = TIMEOUT_C then
148  -- Reset the timer
149  v.timer := 0;
150  -- Update the bandwidth measurement
151  v.updated := '1';
152  v.bandwidth := r.accum;
153  -- Reset the accumulator
154  if r.tValid = '0' then
155  v.accum := (others => '0');
156  else
157  v.accum := toSlv(getTKeep(r.tKeep), 40);
158  end if;
159  end if;
160 
161  -- Check for update previous clock cycle
162  if (r.updated = '1') then
163  -- Set the flag
164  v.updateStat := '1';
165  -- Check if first time after reset
166  if (r.armed = '0') then
167  -- Set the flag
168  v.armed := '1';
169  -- Pass the current values to the statistics measurements
170  v.bandwidthMax := r.bandwidth;
171  v.bandwidthMin := r.bandwidth;
172  else
173  -- Compare for max. value
174  if (r.bandwidth > r.bandwidthMax) then
175  -- Update the statistics measurement
176  v.bandwidthMax := r.accum;
177  end if;
178  -- Compare for min. value
179  if (r.bandwidth < r.bandwidthMin) then
180  -- Update the statistics measurement
181  v.bandwidthMin := r.bandwidth;
182  end if;
183  end if;
184  end if;
185 
186  -- Reset
187  if axisRst = '1' then
188  -- Re-arm and reset statistics measurements only
189  v.armed := '0';
190  v.bandwidthMax := r.bandwidth;
191  v.bandwidthMin := r.bandwidth;
192  end if;
193 
194  -- Register the variable for next clock cycle
195  rin <= v;
196 
197  end process comb;
198 
199  seq : process (axisClk) is
200  begin
201  if rising_edge(axisClk) then
202  r <= rin after TPD_G;
203  end if;
204  end process seq;
205 
206  SyncOut_bandwidth : entity work.SynchronizerFifo
207  generic map (
208  TPD_G => TPD_G,
210  DATA_WIDTH_G => 40)
211  port map (
212  wr_clk => axisClk,
213  wr_en => r.updated,
214  din => r.bandwidth,
215  rd_clk => statusClk,
216  dout => bw);
217 
218  SyncOut_bandwidthMax : entity work.SynchronizerFifo
219  generic map (
220  TPD_G => TPD_G,
222  DATA_WIDTH_G => 40)
223  port map (
224  wr_clk => axisClk,
225  wr_en => r.updateStat,
226  din => r.bandwidthMax,
227  rd_clk => statusClk,
228  dout => bwMax);
229 
230  SyncOut_bandwidthMin : entity work.SynchronizerFifo
231  generic map (
232  TPD_G => TPD_G,
234  DATA_WIDTH_G => 40)
235  port map (
236  wr_clk => axisClk,
237  wr_en => r.updateStat,
238  din => r.bandwidthMin,
239  rd_clk => statusClk,
240  dout => bwMin);
241 
242  bandwidth <= x"000000" & bw;
243  bandwidthMax <= x"000000" & bwMax;
244  bandwidthMin <= x"000000" & bwMin;
245 
246 end rtl;
COMMON_CLK_Gboolean := false
in axisSlaveAxiStreamSlaveType
out bandwidthMaxslv( 63 downto 0)
AXIS_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
in locRstsl := '1'
std_logic sl
Definition: StdRtlPkg.vhd:28
in dinslv( DATA_WIDTH_G- 1 downto 0)
slv( 15 downto 0) tKeep
out bandwidthMinslv( 63 downto 0)
out frameRateslv( 31 downto 0)
natural range 1 to 16 TDATA_BYTES_C
out doutslv( DATA_WIDTH_G- 1 downto 0)
REFRESH_RATE_Greal := 1.0E+0
TPD_Gtime := 1 ns
COMMON_CLK_Gboolean := false
COMMON_CLK_Gboolean := false
out frameRateMaxslv( 31 downto 0)
in refRstsl := '0'
out trigRateOutMinslv( CNT_WIDTH_G- 1 downto 0)
CNT_WIDTH_Gpositive := 32
out bandwidthslv( 63 downto 0)
AXIS_CLK_FREQ_Greal := 156.25E+6
TPD_Gtime := 1 ns
out trigRateOutMaxslv( CNT_WIDTH_G- 1 downto 0)
AxiStreamConfigType :=(TSTRB_EN_C => false,TDATA_BYTES_C => 16,TDEST_BITS_C => 4,TID_BITS_C => 0,TKEEP_MODE_C => TKEEP_NORMAL_C,TUSER_BITS_C => 4,TUSER_MODE_C => TUSER_NORMAL_C) AXI_STREAM_CONFIG_INIT_C
REF_CLK_FREQ_Greal := 200.0E+6
in axisMasterAxiStreamMasterType
out frameRateMinslv( 31 downto 0)
out trigRateOutslv( CNT_WIDTH_G- 1 downto 0)
_library_ ieeeieee
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
std_logic_vector slv
Definition: StdRtlPkg.vhd:29