SURF  1.0
FifoOutputPipeline.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : FifoOutputPipeline.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2014-05-05
5 -- Last update: 2016-09-06
6 -------------------------------------------------------------------------------
7 -- Description: This module is used to sync a FWFT FIFO bus
8 -- either as a pass through or with pipeline register stages.
9 -------------------------------------------------------------------------------
10 -- This file is part of 'SLAC Firmware Standard Library'.
11 -- It is subject to the license terms in the LICENSE.txt file found in the
12 -- top-level directory of this distribution and at:
13 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
14 -- No part of 'SLAC Firmware Standard Library', including this file,
15 -- may be copied, modified, propagated, or distributed except according to
16 -- the terms contained in the LICENSE.txt file.
17 -------------------------------------------------------------------------------
18 
19 library ieee;
20 use ieee.std_logic_1164.all;
21 
22 use work.StdRtlPkg.all;
23 
24 --! @see entity
25  --! @ingroup base_fifo
27  generic (
28  TPD_G : time := 1 ns;
29  RST_POLARITY_G : sl := '1'; -- '1' for active high rst, '0' for active low
30  RST_ASYNC_G : boolean := false;
31  DATA_WIDTH_G : integer range 1 to (2**24) := 16;
32  PIPE_STAGES_G : natural range 0 to 16 := 1);
33  port (
34  -- Slave Port
35  sData : in slv(DATA_WIDTH_G-1 downto 0);
36  sValid : in sl;
37  sRdEn : out sl;
38  -- Master Port
39  mData : out slv(DATA_WIDTH_G-1 downto 0);
40  mValid : out sl;
41  mRdEn : in sl;
42  -- Clock and Reset
43  clk : in sl;
44  rst : in sl := not RST_POLARITY_G); -- Optional reset
45 end FifoOutputPipeline;
46 
47 architecture rtl of FifoOutputPipeline is
48 
49  constant PIPE_STAGES_C : natural := PIPE_STAGES_G+1;
50 
51  type DataArray is array (natural range <>) of slv(DATA_WIDTH_G-1 downto 0);
52 
53  type RegType is record
54  sRdEn : sl;
55  mValid : slv(0 to PIPE_STAGES_C);
56  mData : DataArray(0 to PIPE_STAGES_C);
57  end record RegType;
58 
59  constant REG_INIT_C : RegType := (
60  sRdEn => '0',
61  mValid => (others => '0'),
62  mData => (others => (others => '0')));
63 
64  signal r : RegType := REG_INIT_C;
65  signal rin : RegType;
66 
67 begin
68 
69  ZERO_LATENCY : if (PIPE_STAGES_G = 0) generate
70 
71  mData <= sData;
72  mValid <= sValid;
73  sRdEn <= mRdEn;
74 
75  end generate;
76 
77  PIPE_REG : if (PIPE_STAGES_G > 0) generate
78 
79  comb : process (mRdEn, r, rst, sData, sValid) is
80  variable v : RegType;
81  variable i : natural;
82  begin
83  -- Latch the current value
84  v := r;
85 
86  -- Check if we need to shift register
87  if (r.mValid(PIPE_STAGES_C) = '0') or (mRdEn = '1') then
88  -- Shift the data up the pipeline
89  for i in PIPE_STAGES_C downto 2 loop
90  v.mValid(i) := r.mValid(i-1);
91  v.mData(i) := r.mData(i-1);
92  end loop;
93 
94  -- Check if the lowest cell is empty
95  if r.mValid(0) = '0' then
96  -- Set the read bit
97  v.sRdEn := '1';
98  -- Check if we were pulling the FIFO last clock cycle
99  if r.sRdEn = '1' then
100  -- Shift the FIFO data
101  v.mValid(1) := sValid;
102  v.mData(1) := sData;
103  else
104  -- Clear valid in stage 1
105  v.mValid(1) := '0';
106  end if;
107  else
108  -- Shift the lowest cell
109  v.mValid(1) := r.mValid(0);
110  v.mData(1) := r.mData(0);
111  -- Check if we were pulling the FIFO last clock cycle
112  if r.sRdEn = '1' then
113  -- Reset the read bit
114  v.sRdEn := '0';
115  -- Fill the lowest cell
116  v.mValid(0) := sValid;
117  v.mData(0) := sData;
118  else
119  -- Set the read bit
120  v.sRdEn := '1';
121  -- Reset the lowest cell mValid
122  v.mValid(0) := '0';
123  end if;
124  end if;
125  else
126  -- Reset the read bit
127  v.sRdEn := '0';
128  -- Check if we were pulling the FIFO last clock cycle
129  if r.sRdEn = '1' then
130  -- Fill the lowest cell
131  v.mValid(0) := sValid;
132  v.mData(0) := sData;
133  elsif r.mValid(0) = '0' then
134  -- Set the read bit
135  v.sRdEn := '1';
136  end if;
137  -- Check if we need to internally shift the data to remove gaps
138  for i in PIPE_STAGES_C-1 downto 1 loop
139  -- Check for empty cell ahead of a filled cell
140  if (r.mValid(i) = '0') and (r.mValid(i-1) = '1') then
141  -- Shift the lowest cell
142  v.mValid(i) := r.mValid(i-1);
143  v.mData(i) := r.mData(i-1);
144  -- Reset the flag
145  v.mValid(i-1) := '0';
146  end if;
147  end loop;
148  end if;
149 
150  -- Synchronous Reset
151  if (RST_ASYNC_G = false and rst = RST_POLARITY_G) then
152  v := REG_INIT_C;
153  end if;
154 
155  -- Register the variable for next clock cycle
156  rin <= v;
157 
158  -- Outputs
159  sRdEn <= r.sRdEn;
160  mValid <= r.mValid(PIPE_STAGES_C);
161  mData <= r.mData(PIPE_STAGES_C);
162 
163  end process comb;
164 
165  seq : process (clk, rst) is
166  begin
167  if rising_edge(clk) then
168  r <= rin after TPD_G;
169  end if;
170  -- Asynchronous Reset
171  if (RST_ASYNC_G and rst = RST_POLARITY_G) then
172  r <= REG_INIT_C after TPD_G;
173  end if;
174  end process seq;
175 
176  end generate;
177 
178 end rtl;
_library_ ieeeieee
Definition: FifoMux.vhd:18
RST_ASYNC_Gboolean := false
std_logic sl
Definition: StdRtlPkg.vhd:28
in rstsl :=not RST_POLARITY_G
PIPE_STAGES_Gnatural range 0 to 16:= 1
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
in sDataslv( DATA_WIDTH_G- 1 downto 0)
out mDataslv( DATA_WIDTH_G- 1 downto 0)
std_logic_vector slv
Definition: StdRtlPkg.vhd:29