1 -------------------------------------------------------------------------------
2 -- Title : Parametrilayze based on SRL16 shift register FIFO
3 -- Project :
4 -------------------------------------------------------------------------------
5 -- File : fifo_srl_uni.vhd
6 -- Author : Tomasz Turek <tomasz.turek@gmail.com>
7 -- Company : SzuWar INC
8 -- Created : 13:27:31 14-03-2010
9 -- Last update: 15:02:32 21-03-2010
10 -- Platform : Xilinx ISE 10.1.03
11 -- Standard : VHDL'93
12 -------------------------------------------------------------------------------
13 -- Description:
14 -------------------------------------------------------------------------------
15 -- Copyright (c) 2010 SzuWar INC
16 -------------------------------------------------------------------------------
17 -- Revisions :
18 -- Date Version Author Description
19 -- 13:27:31 14-03-2010 1.0 szuwarek Created
20 -------------------------------------------------------------------------------
21 -- Version 1.1 unlimited size of Input and Output register.
22 -- Version 1.0
23
24 library IEEE;
25 use IEEE.STD_LOGIC_1164.all;
26 use ieee.std_logic_arith.all;
27 use IEEE.STD_LOGIC_UNSIGNED.all;
28
29 library UNISIM;
30 use UNISIM.vcomponents.all;
31
32 entity fifo_srl_uni is
33
34 generic (
35 iDataWidth : integer range 1 to 32 := 17;
36 ififoWidth : integer range 1 to 1023 := 32;
37 iInputReg : integer range 0 to 3 := 0;
38 iOutputReg : integer range 0 to 3 := 2;
39 iFullFlagOfSet : integer range 0 to 1021 := 2;
40 iEmptyFlagOfSet : integer range 0 to 1021 := 5;
41 iSizeDelayCounter : integer range 5 to 11 := 6
42 );
43
44 port (
45 CLK_I : in std_logic;
46 DATA_I : in std_logic_vector(iDataWidth - 1 downto 0);
47 DATA_O : out std_logic_vector(iDataWidth - 1 downto 0);
48 WRITE_ENABLE_I : in std_logic;
49 READ_ENABLE_I : in std_logic;
50 READ_VALID_O : out std_logic;
51 FIFO_COUNT_O : out std_logic_vector(iSizeDelayCounter - 1 downto 0);
52 FULL_FLAG_O : out std_logic;
53 EMPTY_FLAG_O : out std_logic
54 );
55
56 end entity fifo_srl_uni;
57
58 architecture fifo_srl_uni_rtl of fifo_srl_uni is
59
60 -------------------------------------------------------------------------------
61 -- functions --
62 -------------------------------------------------------------------------------
63 function f_srl_count (constant c_fifo_size : integer) return integer is
64
65 variable i_temp : integer;
66 variable i_count : integer;
67
68 begin -- function f_srl_count
69
70 i_temp := c_fifo_size;
71 i_count := 0;
72
73 for i in 0 to 64 loop
74
75 if i_temp < 1 then
76
77 if i_count = 0 then
78
79 i_count := i;
80
81 else
82
83 i_count := i_count;
84
85 end if;
86
87 else
88
89 i_temp := i_temp - 16;
90
91 end if;
92
93 end loop; -- i
94
95 return i_count;
96
97 end function f_srl_count;
98
99 -------------------------------------------------------------------------------
100 -- constants --
101 -------------------------------------------------------------------------------
102 constant c_srl_count : integer range 0 to 64 := f_srl_count(ififoWidth);
103
104 -------------------------------------------------------------------------------
105 -- types --
106 -------------------------------------------------------------------------------
107 type type_in_reg is array (0 to iInputReg - 1) of std_logic_vector(iDataWidth - 1 downto 0);
108 type type_out_reg is array (0 to iOutputReg) of std_logic_vector(iDataWidth - 1 downto 0);
109 type type_data_path is array (0 to c_srl_count - 1) of std_logic_vector(iDataWidth - 1 downto 0);
110 type type_srl_path is array (0 to c_srl_count) of std_logic_vector(iDataWidth - 1 downto 0);
111
112 -------------------------------------------------------------------------------
113 -- signals --
114 -------------------------------------------------------------------------------
115 signal v_delay_counter : std_logic_vector(iSizeDelayCounter - 1 downto 0) := (others => '0');
116 signal v_size_counter : std_logic_vector(iSizeDelayCounter - 1 downto 0) := (others => '0');
117 signal v_zeros : std_logic_vector(iSizeDelayCounter - 1 downto 0) := (others => '0');
118 signal v_WRITE_ENABLE : std_logic_vector(iInputReg downto 0);
119 signal v_READ_ENABLE : std_logic_vector(iOutputReg downto 0);
120 signal v_valid_delay : std_logic_vector(iOutputReg downto 0);
121 signal i_size_counter : integer range 0 to 1023 := 0;
122 signal i_srl_select : integer range 0 to 64 := 0;
123 signal i_temp : integer range 0 to 64;
124 signal t_mux_in : type_data_path;
125 signal t_srl_in : type_srl_path;
126 signal t_mux_out : type_out_reg;
127 signal t_reg_in : type_in_reg;
128 signal one_delay : std_logic := '0';
129 signal ce_master : std_logic;
130 signal full_capacity : std_logic;
131 signal data_valid_off : std_logic;
132
133 begin -- architecture fifo_srl_uni_r
134
135 v_zeros <= (others => '0');
136
137 i_srl_select <= conv_integer((v_delay_counter(iSizeDelayCounter - 1 downto 4)));
138 i_size_counter <= conv_integer(v_size_counter);
139
140 ce_master <= v_WRITE_ENABLE(0) and (not full_capacity);
141
142 full_capacity <= '0' when i_size_counter < ififoWidth else '1';
143
144 t_mux_out(0) <= t_mux_in(i_srl_select);
145 READ_VALID_O <= v_READ_ENABLE(0) and (not v_valid_delay(0));
146 FIFO_COUNT_O <= v_size_counter;
147
148 -------------------------------------------------------------------------------
149 -- Input Register --
150 -------------------------------------------------------------------------------
151 GR0 : if iInputReg = 0 generate
152
153 t_srl_in(0) <= DATA_I;
154 v_WRITE_ENABLE(iInputReg) <= WRITE_ENABLE_I;
155
156 end generate GR0;
157
158 GR1 : if iInputReg = 1 generate
159
160 t_srl_in(0) <= t_reg_in(0);
161 v_WRITE_ENABLE(iInputReg) <= WRITE_ENABLE_I;
162
163 P1 : process (CLK_I) is
164 begin -- process P1
165
166 if rising_edge(CLK_I) then
167
168 t_reg_in(0) <= DATA_I;
169 v_WRITE_ENABLE(0) <= v_WRITE_ENABLE(iInputReg);
170
171 end if;
172
173 end process P1;
174
175 end generate GR1;
176
177 GR2 : if iInputReg > 1 generate
178
179 t_srl_in(0) <= t_reg_in(0);
180 v_WRITE_ENABLE(iInputReg) <= WRITE_ENABLE_I;
181
182 P1 : process (CLK_I) is
183 begin -- process P1
184
185 if rising_edge(CLK_I) then
186
187 t_reg_in(iInputReg - 1) <= DATA_I;
188 t_reg_in(0 to iInputReg - 2) <= t_reg_in(1 to iInputReg -1);
189 v_WRITE_ENABLE(iInputReg - 1 downto 0) <= v_WRITE_ENABLE(iInputReg downto 1);
190
191 end if;
192
193 end process P1;
194
195 end generate GR2;
196 -------------------------------------------------------------------------------
197 -- Input Register --
198 -------------------------------------------------------------------------------
199
200 -------------------------------------------------------------------------------
201 -- FIFO Core, SRL16E based --
202 -------------------------------------------------------------------------------
203 G1 : for i in 0 to c_srl_count - 1 generate
204
205 G0 : for j in 0 to iDataWidth - 1 generate
206
207 SRLC16_inst : SRLC16E
208 port map
209 (
210 Q => t_mux_in(i)(j), -- SRL data output
211 Q15 => t_srl_in(i+1)(j), -- Carry output (connect to next SRL)
212 A0 => v_delay_counter(0), -- Select[0] input
213 A1 => v_delay_counter(1), -- Select[1] input
214 A2 => v_delay_counter(2), -- Select[2] input
215 A3 => v_delay_counter(3), -- Select[3] input
216 CE => ce_master, -- Clock enable input
217 CLK => CLK_I, -- Clock input
218 D => t_srl_in(i)(j) -- SRL data input
219 );
220
221 end generate G0;
222
223 end generate G1;
224 -------------------------------------------------------------------------------
225 -- FIFO Core, SRL16E based --
226 -------------------------------------------------------------------------------
227
228 P0 : process (CLK_I) is
229 begin -- process P0
230
231 if rising_edge(CLK_I) then
232
233 if (v_WRITE_ENABLE(0) = '1') and (READ_ENABLE_I = '0') and (i_size_counter < ififoWidth) then
234
235 if one_delay = '1' then
236
237 v_delay_counter <= v_delay_counter + 1;
238 one_delay <= '1';
239
240 else
241
242 one_delay <= '1';
243 v_delay_counter <= v_delay_counter;
244
245 end if;
246
247 v_size_counter <= v_size_counter + 1;
248
249 elsif (v_WRITE_ENABLE(0) = '0') and (READ_ENABLE_I = '1') and (i_size_counter > 0) then
250
251 if v_delay_counter = v_zeros then
252
253 one_delay <= '0';
254
255 else
256
257 one_delay <= '1';
258 v_delay_counter <= v_delay_counter - 1;
259
260 end if;
261
262 v_size_counter <= v_size_counter - 1;
263
264 else
265
266 v_delay_counter <= v_delay_counter;
267 v_size_counter <= v_size_counter;
268 one_delay <= one_delay;
269
270 end if;
271
272 end if;
273
274 end process P0;
275
276 data_valid_off <= '1' when i_size_counter = 0 else '0';
277 -------------------------------------------------------------------------------
278 -- Output Register --
279 -------------------------------------------------------------------------------
280
281 -- size of output register: 0 --
282 GM0 : if iOutputReg = 0 generate
283
284 DATA_O <= t_mux_out(0);
285 v_READ_ENABLE(0) <= READ_ENABLE_I;
286 v_valid_delay(0) <= data_valid_off;
287
288 end generate GM0;
289
290 -- size of output register: 1 --
291 GM1 : if iOutputReg = 1 generate
292
293 DATA_O <= t_mux_out(1);
294 v_READ_ENABLE(1) <= READ_ENABLE_I;
295
296
297 P2 : process (CLK_I) is
298 begin -- process P2
299
300 if rising_edge(CLK_I) then
301
302 v_READ_ENABLE(0) <= v_READ_ENABLE(1);
303 t_mux_out(1) <= t_mux_out(0);
304 v_valid_delay(0) <= data_valid_off;
305
306 end if;
307
308 end process P2;
309
310 end generate GM1;
311
312 -- size of output register: > 1 --
313 GM2 : if iOutputReg > 1 generate
314
315 DATA_O <= t_mux_out(iOutputReg);
316 v_READ_ENABLE(iOutputReg) <= READ_ENABLE_I;
317
318 P2 : process (CLK_I) is
319 begin -- process P2
320
321 if rising_edge(CLK_I) then
322
323 v_READ_ENABLE(iOutputReg - 1 downto 0) <= v_READ_ENABLE(iOutputReg downto 1);
324 t_mux_out(1 to iOutputReg) <= t_mux_out(0 to iOutputReg - 1);
325 v_valid_delay(iOutputReg - 1 downto 0) <= data_valid_off & v_valid_delay(iOutputReg - 1 downto 1);
326
327 end if;
328
329 end process P2;
330
331 end generate GM2;
332 -------------------------------------------------------------------------------
333 -- Output Register --
334 -------------------------------------------------------------------------------
335
336 -------------------------------------------------------------------------------
337 -- Flag Generators --
338 -------------------------------------------------------------------------------
339 EMPTY_FLAG_O <= '0' when (i_size_counter) > iEmptyFlagOfSet else '1';
340 FULL_FLAG_O <= '1' when i_size_counter >= ififoWidth - iFullFlagOfSet else '0';
341 -------------------------------------------------------------------------------
342 -- Flag Generators --
343 -------------------------------------------------------------------------------
344
345 end architecture fifo_srl_uni_rtl;