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;