otsdaq_prepmodernization  v2_05_02_indev
ADDR_FIFO_pctrl.vhd
1 
2 --------------------------------------------------------------------------------
3 --
4 -- FIFO Generator Core Demo Testbench
5 --
6 --------------------------------------------------------------------------------
7 --
8 -- (c) Copyright 2009 - 2010 Xilinx, Inc. All rights reserved.
9 --
10 -- This file contains confidential and proprietary information
11 -- of Xilinx, Inc. and is protected under U.S. and
12 -- international copyright and other intellectual property
13 -- laws.
14 --
15 -- DISCLAIMER
16 -- This disclaimer is not a license and does not grant any
17 -- rights to the materials distributed herewith. Except as
18 -- otherwise provided in a valid license issued to you by
19 -- Xilinx, and to the maximum extent permitted by applicable
20 -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
21 -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
22 -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
23 -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
24 -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
25 -- (2) Xilinx shall not be liable (whether in contract or tort,
26 -- including negligence, or under any other theory of
27 -- liability) for any loss or damage of any kind or nature
28 -- related to, arising under or in connection with these
29 -- materials, including for any direct, or any indirect,
30 -- special, incidental, or consequential loss or damage
31 -- (including loss of data, profits, goodwill, or any type of
32 -- loss or damage suffered as a result of any action brought
33 -- by a third party) even if such damage or loss was
34 -- reasonably foreseeable or Xilinx had been advised of the
35 -- possibility of the same.
36 --
37 -- CRITICAL APPLICATIONS
38 -- Xilinx products are not designed or intended to be fail-
39 -- safe, or for use in any application requiring fail-safe
40 -- performance, such as life-support or safety devices or
41 -- systems, Class III medical devices, nuclear facilities,
42 -- applications related to the deployment of airbags, or any
43 -- other applications that could lead to death, personal
44 -- injury, or severe property or environmental damage
45 -- (individually and collectively, "Critical
46 -- Applications"). Customer assumes the sole risk and
47 -- liability of any use of Xilinx products in Critical
48 -- Applications, subject only to applicable laws and
49 -- regulations governing limitations on product liability.
50 --
51 -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
52 -- PART OF THIS FILE AT ALL TIMES.
53 --------------------------------------------------------------------------------
54 --
55 -- Filename: ADDR_FIFO_pctrl.vhd
56 --
57 -- Description:
58 -- Used for protocol control on write and read interface stimulus and status generation
59 --
60 --------------------------------------------------------------------------------
61 -- Library Declarations
62 --------------------------------------------------------------------------------
63 LIBRARY ieee;
64 USE ieee.std_logic_1164.ALL;
65 USE ieee.std_logic_unsigned.all;
66 USE IEEE.std_logic_arith.all;
67 USE IEEE.std_logic_misc.all;
68 
69 LIBRARY work;
70 USE work.ADDR_FIFO_pkg.ALL;
71 
72 ENTITY ADDR_FIFO_pctrl IS
73  GENERIC(
74  AXI_CHANNEL : STRING :="NONE";
75  C_APPLICATION_TYPE : INTEGER := 0;
76  C_DIN_WIDTH : INTEGER := 0;
77  C_DOUT_WIDTH : INTEGER := 0;
78  C_WR_PNTR_WIDTH : INTEGER := 0;
79  C_RD_PNTR_WIDTH : INTEGER := 0;
80  C_CH_TYPE : INTEGER := 0;
81  FREEZEON_ERROR : INTEGER := 0;
82  TB_STOP_CNT : INTEGER := 2;
83  TB_SEED : INTEGER := 2
84  );
85  PORT(
86  RESET_WR : IN STD_LOGIC;
87  RESET_RD : IN STD_LOGIC;
88  WR_CLK : IN STD_LOGIC;
89  RD_CLK : IN STD_LOGIC;
90  FULL : IN STD_LOGIC;
91  EMPTY : IN STD_LOGIC;
92  ALMOST_FULL : IN STD_LOGIC;
93  ALMOST_EMPTY : IN STD_LOGIC;
94  DATA_IN : IN STD_LOGIC_VECTOR(C_DIN_WIDTH-1 DOWNTO 0);
95  DATA_OUT : IN STD_LOGIC_VECTOR(C_DOUT_WIDTH-1 DOWNTO 0);
96  DOUT_CHK : IN STD_LOGIC;
97  PRC_WR_EN : OUT STD_LOGIC;
98  PRC_RD_EN : OUT STD_LOGIC;
99  RESET_EN : OUT STD_LOGIC;
100  SIM_DONE : OUT STD_LOGIC;
101  STATUS : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
102  );
103 END ENTITY;
104 
105 
106 ARCHITECTURE fg_pc_arch OF ADDR_FIFO_pctrl IS
107 
108  CONSTANT C_DATA_WIDTH : INTEGER := if_then_else(C_DIN_WIDTH > C_DOUT_WIDTH,C_DIN_WIDTH,C_DOUT_WIDTH);
109  CONSTANT LOOP_COUNT : INTEGER := divroundup(C_DATA_WIDTH,8);
110  CONSTANT D_WIDTH_DIFF : INTEGER := log2roundup(C_DOUT_WIDTH/C_DIN_WIDTH);
111 
112  SIGNAL data_chk_i : STD_LOGIC := if_then_else(C_CH_TYPE /= 2,'1','0');
113  SIGNAL full_chk_i : STD_LOGIC := if_then_else(C_CH_TYPE /= 2,'1','0');
114  SIGNAL empty_chk_i : STD_LOGIC := if_then_else(C_CH_TYPE /= 2,'1','0');
115  SIGNAL status_i : STD_LOGIC_VECTOR(4 DOWNTO 0):= (OTHERS => '0');
116  SIGNAL status_d1_i : STD_LOGIC_VECTOR(4 DOWNTO 0):= (OTHERS => '0');
117  SIGNAL wr_en_gen : STD_LOGIC_VECTOR(7 DOWNTO 0):= (OTHERS => '0');
118  SIGNAL rd_en_gen : STD_LOGIC_VECTOR(7 DOWNTO 0):= (OTHERS => '0');
119  SIGNAL wr_cntr : STD_LOGIC_VECTOR(C_WR_PNTR_WIDTH-2 DOWNTO 0) := (OTHERS => '0');
120  SIGNAL full_as_timeout : STD_LOGIC_VECTOR(C_WR_PNTR_WIDTH DOWNTO 0) := (OTHERS => '0');
121  SIGNAL full_ds_timeout : STD_LOGIC_VECTOR(C_WR_PNTR_WIDTH DOWNTO 0) := (OTHERS => '0');
122  SIGNAL rd_cntr : STD_LOGIC_VECTOR(C_RD_PNTR_WIDTH-2 DOWNTO 0) := (OTHERS => '0');
123  SIGNAL empty_as_timeout : STD_LOGIC_VECTOR(C_RD_PNTR_WIDTH DOWNTO 0) := (OTHERS => '0');
124  SIGNAL empty_ds_timeout : STD_LOGIC_VECTOR(C_RD_PNTR_WIDTH DOWNTO 0):= (OTHERS => '0');
125  SIGNAL wr_en_i : STD_LOGIC := '0';
126  SIGNAL rd_en_i : STD_LOGIC := '0';
127  SIGNAL state : STD_LOGIC := '0';
128  SIGNAL wr_control : STD_LOGIC := '0';
129  SIGNAL rd_control : STD_LOGIC := '0';
130  SIGNAL stop_on_err : STD_LOGIC := '0';
131  SIGNAL sim_stop_cntr : STD_LOGIC_VECTOR(7 DOWNTO 0):= conv_std_logic_vector(if_then_else(C_CH_TYPE=2,64,TB_STOP_CNT),8);
132  SIGNAL sim_done_i : STD_LOGIC := '0';
133  SIGNAL rdw_gt_wrw : STD_LOGIC_VECTOR(D_WIDTH_DIFF-1 DOWNTO 0) := (OTHERS => '1');
134  SIGNAL wrw_gt_rdw : STD_LOGIC_VECTOR(D_WIDTH_DIFF-1 DOWNTO 0) := (OTHERS => '1');
135  SIGNAL rd_activ_cont : STD_LOGIC_VECTOR(25 downto 0):= (OTHERS => '0');
136  SIGNAL prc_we_i : STD_LOGIC := '0';
137  SIGNAL prc_re_i : STD_LOGIC := '0';
138  SIGNAL reset_en_i : STD_LOGIC := '0';
139  SIGNAL state_d1 : STD_LOGIC := '0';
140  SIGNAL post_rst_dly_wr : STD_LOGIC_VECTOR(4 DOWNTO 0) := (OTHERS => '1');
141  SIGNAL post_rst_dly_rd : STD_LOGIC_VECTOR(4 DOWNTO 0) := (OTHERS => '1');
142 BEGIN
143  status_i <= data_chk_i & full_chk_i & empty_chk_i & '0' & '0';
144  STATUS <= status_d1_i & '0' & '0' & rd_activ_cont(rd_activ_cont'high);
145 
146  prc_we_i <= wr_en_i WHEN sim_done_i = '0' ELSE '0';
147  prc_re_i <= rd_en_i WHEN sim_done_i = '0' ELSE '0';
148 
149  SIM_DONE <= sim_done_i;
150  rdw_gt_wrw <= (OTHERS => '1');
151  wrw_gt_rdw <= (OTHERS => '1');
152 
153  PROCESS(RD_CLK)
154  BEGIN
155  IF (RD_CLK'event AND RD_CLK='1') THEN
156  IF(prc_re_i = '1') THEN
157  rd_activ_cont <= rd_activ_cont + "1";
158  END IF;
159  END IF;
160  END PROCESS;
161 
162 
163  PROCESS(sim_done_i)
164  BEGIN
165  assert sim_done_i = '0'
166  report "Simulation Complete for:" & AXI_CHANNEL
167  severity note;
168  END PROCESS;
169 
170 -----------------------------------------------------
171 -- SIM_DONE SIGNAL GENERATION
172 -----------------------------------------------------
173 PROCESS (RD_CLK,RESET_RD)
174 BEGIN
175  IF(RESET_RD = '1') THEN
176  --sim_done_i <= '0';
177  ELSIF(RD_CLK'event AND RD_CLK='1') THEN
178  IF((OR_REDUCE(sim_stop_cntr) = '0' AND TB_STOP_CNT /= 0) OR stop_on_err = '1') THEN
179  sim_done_i <= '1';
180  END IF;
181  END IF;
182 END PROCESS;
183 
184  -- TB Timeout/Stop
185  fifo_tb_stop_run:IF(TB_STOP_CNT /= 0) GENERATE
186  PROCESS (RD_CLK)
187  BEGIN
188  IF (RD_CLK'event AND RD_CLK='1') THEN
189  IF(state = '0' AND state_d1 = '1') THEN
190  sim_stop_cntr <= sim_stop_cntr - "1";
191  END IF;
192  END IF;
193  END PROCESS;
194  END GENERATE fifo_tb_stop_run;
195 
196 
197  -- Stop when error found
198  PROCESS (RD_CLK)
199  BEGIN
200  IF (RD_CLK'event AND RD_CLK='1') THEN
201  IF(sim_done_i = '0') THEN
202  status_d1_i <= status_i OR status_d1_i;
203  END IF;
204  IF(FREEZEON_ERROR = 1 AND status_i /= "0") THEN
205  stop_on_err <= '1';
206  END IF;
207  END IF;
208  END PROCESS;
209  -----------------------------------------------------
210 
211  -----------------------------------------------------
212  -- CHECKS FOR FIFO
213  -----------------------------------------------------
214 
215 
216  PROCESS(RD_CLK,RESET_RD)
217  BEGIN
218  IF(RESET_RD = '1') THEN
219  post_rst_dly_rd <= (OTHERS => '1');
220  ELSIF (RD_CLK'event AND RD_CLK='1') THEN
221  post_rst_dly_rd <= post_rst_dly_rd-post_rst_dly_rd(4);
222  END IF;
223  END PROCESS;
224 
225  PROCESS(WR_CLK,RESET_WR)
226  BEGIN
227  IF(RESET_WR = '1') THEN
228  post_rst_dly_wr <= (OTHERS => '1');
229  ELSIF (WR_CLK'event AND WR_CLK='1') THEN
230  post_rst_dly_wr <= post_rst_dly_wr-post_rst_dly_wr(4);
231  END IF;
232  END PROCESS;
233 
234 
235  -- FULL de-assert Counter
236  PROCESS(WR_CLK,RESET_WR)
237  BEGIN
238  IF(RESET_WR = '1') THEN
239  full_ds_timeout <= (OTHERS => '0');
240  ELSIF(WR_CLK'event AND WR_CLK='1') THEN
241  IF(state = '1') THEN
242  IF(rd_en_i = '1' AND wr_en_i = '0' AND FULL = '1' AND AND_REDUCE(wrw_gt_rdw) = '1') THEN
243  full_ds_timeout <= full_ds_timeout + '1';
244  END IF;
245  ELSE
246  full_ds_timeout <= (OTHERS => '0');
247  END IF;
248  END IF;
249  END PROCESS;
250 
251 
252  -- EMPTY deassert counter
253  PROCESS(RD_CLK,RESET_RD)
254  BEGIN
255  IF(RESET_RD = '1') THEN
256  empty_ds_timeout <= (OTHERS => '0');
257  ELSIF(RD_CLK'event AND RD_CLK='1') THEN
258  IF(state = '0') THEN
259  IF(wr_en_i = '1' AND rd_en_i = '0' AND EMPTY = '1' AND AND_REDUCE(rdw_gt_wrw) = '1') THEN
260  empty_ds_timeout <= empty_ds_timeout + '1';
261  END IF;
262  ELSE
263  empty_ds_timeout <= (OTHERS => '0');
264  END IF;
265  END IF;
266  END PROCESS;
267 
268  -- Full check signal generation
269  PROCESS(WR_CLK,RESET_WR)
270  BEGIN
271  IF(RESET_WR = '1') THEN
272  full_chk_i <= '0';
273  ELSIF(WR_CLK'event AND WR_CLK='1') THEN
274  IF(C_APPLICATION_TYPE = 1 AND (AXI_CHANNEL = "WACH" OR AXI_CHANNEL = "RACH" OR AXI_CHANNEL = "AXI4_Stream")) THEN
275  full_chk_i <= '0';
276  ELSE
277  full_chk_i <= AND_REDUCE(full_as_timeout) OR
278  AND_REDUCE(full_ds_timeout);
279  END IF;
280  END IF;
281  END PROCESS;
282 
283  -- Empty checks
284  PROCESS(RD_CLK,RESET_RD)
285  BEGIN
286  IF(RESET_RD = '1') THEN
287  empty_chk_i <= '0';
288  ELSIF(RD_CLK'event AND RD_CLK='1') THEN
289  IF(C_APPLICATION_TYPE = 1 AND (AXI_CHANNEL = "WACH" OR AXI_CHANNEL = "RACH" OR AXI_CHANNEL = "AXI4_Stream")) THEN
290  empty_chk_i <= '0';
291  ELSE
292  empty_chk_i <= AND_REDUCE(empty_as_timeout) OR
293  AND_REDUCE(empty_ds_timeout);
294  END IF;
295  END IF;
296  END PROCESS;
297 
298  fifo_d_chk:IF(C_CH_TYPE /= 2) GENERATE
299  PRC_WR_EN <= prc_we_i AFTER 50 ns;
300  PRC_RD_EN <= prc_re_i AFTER 50 ns;
301  data_chk_i <= dout_chk;
302  END GENERATE fifo_d_chk;
303  -----------------------------------------------------
304  RESET_EN <= reset_en_i;
305 
306  PROCESS(RD_CLK,RESET_RD)
307  BEGIN
308  IF(RESET_RD = '1') THEN
309  state_d1 <= '0';
310  ELSIF (RD_CLK'event AND RD_CLK='1') THEN
311  state_d1 <= state;
312  END IF;
313  END PROCESS;
314 
315 
316  data_fifo_en:IF(C_CH_TYPE /= 2) GENERATE
317  -----------------------------------------------------
318  -- WR_EN GENERATION
319  -----------------------------------------------------
320  gen_rand_wr_en:ADDR_FIFO_rng
321  GENERIC MAP(
322  WIDTH => 8,
323  SEED => TB_SEED+1
324  )
325  PORT MAP(
326  CLK => WR_CLK,
327  RESET => RESET_WR,
328  RANDOM_NUM => wr_en_gen,
329  ENABLE => '1'
330  );
331 
332  PROCESS(WR_CLK,RESET_WR)
333  BEGIN
334  IF(RESET_WR = '1') THEN
335  wr_en_i <= '0';
336  ELSIF(WR_CLK'event AND WR_CLK='1') THEN
337  IF(state = '1') THEN
338  wr_en_i <= wr_en_gen(0) AND wr_en_gen(7) AND wr_en_gen(2) AND wr_control;
339  ELSE
340  wr_en_i <= (wr_en_gen(3) OR wr_en_gen(4) OR wr_en_gen(2)) AND (NOT post_rst_dly_wr(4));
341  END IF;
342  END IF;
343  END PROCESS;
344 
345  -----------------------------------------------------
346  -- WR_EN CONTROL
347  -----------------------------------------------------
348  PROCESS(WR_CLK,RESET_WR)
349  BEGIN
350  IF(RESET_WR = '1') THEN
351  wr_cntr <= (OTHERS => '0');
352  wr_control <= '1';
353  full_as_timeout <= (OTHERS => '0');
354  ELSIF(WR_CLK'event AND WR_CLK='1') THEN
355  IF(state = '1') THEN
356  IF(wr_en_i = '1') THEN
357  wr_cntr <= wr_cntr + "1";
358  END IF;
359  full_as_timeout <= (OTHERS => '0');
360  ELSE
361  wr_cntr <= (OTHERS => '0');
362  IF(rd_en_i = '0') THEN
363  IF(wr_en_i = '1') THEN
364  full_as_timeout <= full_as_timeout + "1";
365  END IF;
366  ELSE
367  full_as_timeout <= (OTHERS => '0');
368  END IF;
369  END IF;
370 
371  wr_control <= NOT wr_cntr(wr_cntr'high);
372 
373  END IF;
374  END PROCESS;
375 
376  -----------------------------------------------------
377  -- RD_EN GENERATION
378  -----------------------------------------------------
379  gen_rand_rd_en:ADDR_FIFO_rng
380  GENERIC MAP(
381  WIDTH => 8,
382  SEED => TB_SEED
383  )
384  PORT MAP(
385  CLK => RD_CLK,
386  RESET => RESET_RD,
387  RANDOM_NUM => rd_en_gen,
388  ENABLE => '1'
389  );
390 
391  PROCESS(RD_CLK,RESET_RD)
392  BEGIN
393  IF(RESET_RD = '1') THEN
394  rd_en_i <= '0';
395  ELSIF(RD_CLK'event AND RD_CLK='1') THEN
396  IF(state = '0') THEN
397  rd_en_i <= rd_en_gen(1) AND rd_en_gen(5) AND rd_en_gen(3) AND rd_control AND (NOT post_rst_dly_rd(4));
398  ELSE
399  rd_en_i <= rd_en_gen(0) OR rd_en_gen(6);
400  END IF;
401  END IF;
402  END PROCESS;
403 
404  -----------------------------------------------------
405  -- RD_EN CONTROL
406  -----------------------------------------------------
407  PROCESS(RD_CLK,RESET_RD)
408  BEGIN
409  IF(RESET_RD = '1') THEN
410  rd_cntr <= (OTHERS => '0');
411  rd_control <= '1';
412  empty_as_timeout <= (OTHERS => '0');
413  ELSIF(RD_CLK'event AND RD_CLK='1') THEN
414  IF(state = '0') THEN
415  IF(rd_en_i = '1') THEN
416  rd_cntr <= rd_cntr + "1";
417  END IF;
418  empty_as_timeout <= (OTHERS => '0');
419  ELSE
420  rd_cntr <= (OTHERS => '0');
421  IF(wr_en_i = '0') THEN
422  IF(rd_en_i = '1') THEN
423  empty_as_timeout <= empty_as_timeout + "1";
424  END IF;
425  ELSE
426  empty_as_timeout <= (OTHERS => '0');
427  END IF;
428  END IF;
429 
430  rd_control <= NOT rd_cntr(rd_cntr'high);
431 
432  END IF;
433  END PROCESS;
434 
435  -----------------------------------------------------
436  -- STIMULUS CONTROL
437  -----------------------------------------------------
438  PROCESS(WR_CLK,RESET_WR)
439  BEGIN
440  IF(RESET_WR = '1') THEN
441  state <= '0';
442  reset_en_i <= '0';
443  ELSIF(WR_CLK'event AND WR_CLK='1') THEN
444  CASE state IS
445  WHEN '0' =>
446  IF(FULL = '1' AND EMPTY = '0') THEN
447  state <= '1';
448  reset_en_i <= '0';
449  END IF;
450  WHEN '1' =>
451  IF(EMPTY = '1' AND FULL = '0') THEN
452  state <= '0';
453  reset_en_i <= '1';
454  END IF;
455  WHEN OTHERS => state <= state;
456  END CASE;
457  END IF;
458  END PROCESS;
459  END GENERATE data_fifo_en;
460 
461 END ARCHITECTURE;