1 ------------------------------------------------------------------------------- 2 -- Title : Parametrilayze based on SRL16 shift register FIFO 3 -- Project : 4 ------------------------------------------------------------------------------- 5 -- File : fifo_srl_uni.vhd 6 -- Author : Tomasz Turek7 -- 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_r134 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 generate152 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 generate159 160 t_srl_in(0) <= t_reg_in(0);161 v_WRITE_ENABLE(iInputReg) <= WRITE_ENABLE_I;162 163 P1 : process (CLK_I) is164 begin -- process P1165 166 if rising_edge(CLK_I) then167 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 generate178 179 t_srl_in(0) <= t_reg_in(0);180 v_WRITE_ENABLE(iInputReg) <= WRITE_ENABLE_I;181 182 P1 : process (CLK_I) is183 begin -- process P1184 185 if rising_edge(CLK_I) then186 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 generate204 205 G0 : for j in 0 to iDataWidth - 1 generate206 207 SRLC16_inst : SRLC16E208 port map209 (210 Q => t_mux_in(i)(j), -- SRL data output211 Q15 => t_srl_in(i+1)(j), -- Carry output (connect to next SRL)212 A0 => v_delay_counter(0), -- Select[0] input213 A1 => v_delay_counter(1), -- Select[1] input214 A2 => v_delay_counter(2), -- Select[2] input215 A3 => v_delay_counter(3), -- Select[3] input216 CE => ce_master, -- Clock enable input217 CLK => CLK_I, -- Clock input218 D => t_srl_in(i)(j) -- SRL data input219 );220 221 end generate G0;222 223 end generate G1;224 -------------------------------------------------------------------------------225 -- FIFO Core, SRL16E based --226 -------------------------------------------------------------------------------227 228 P0 : process (CLK_I) is229 begin -- process P0230 231 if rising_edge(CLK_I) then232 233 if (v_WRITE_ENABLE(0) = '1') and (READ_ENABLE_I = '0') and (i_size_counter < ififoWidth) then234 235 if one_delay = '1' then236 237 v_delay_counter <= v_delay_counter + 1;238 one_delay <= '1';239 240 else241 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) then250 251 if v_delay_counter = v_zeros then252 253 one_delay <= '0';254 255 else256 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 else265 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 generate283 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 generate292 293 DATA_O <= t_mux_out(1);294 v_READ_ENABLE(1) <= READ_ENABLE_I;295 296 297 P2 : process (CLK_I) is298 begin -- process P2299 300 if rising_edge(CLK_I) then301 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 generate314 315 DATA_O <= t_mux_out(iOutputReg);316 v_READ_ENABLE(iOutputReg) <= READ_ENABLE_I;317 318 P2 : process (CLK_I) is319 begin -- process P2320 321 if rising_edge(CLK_I) then322 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;