00001 --**************************************************************
00002 --* *
00003 --* The source code for the ATLAS BCM "AAA" FPGA is made *
00004 --* available via the GNU General Public License (GPL) *
00005 --* unless otherwise stated below. *
00006 --* *
00007 --* In case of problems/questions/bug reports etc. please *
00008 --* contact michael.niegl@cern.ch *
00009 --* *
00010 --**************************************************************
00011
00012 --**************************************************************
00013 --* *
00014 --* $Source: /local/reps/bcmfpga/bcm_aaa/bcm_aaa/ddr2/ddr2_mem_tap_ctrl.vhd,v $
00015 --* $Revision: 1.3.2.5 $ *
00016 --* $Name: dev $ *
00017 --* $Author: mniegl $ *
00018 --* $Date: 2008/11/03 19:09:26 $ *
00019
00020
00021 --* *
00022 --**************************************************************
00023 -- Copyright (c) 2005 Xilinx, Inc.
00024 -- This design is confidential and proprietary of Xilinx, All Rights Reserved.
00025 -------------------------------------------------------------------------------
00026 -- ____ ____
00027 -- / /\/ /
00028 -- /___/ \ / Vendor: Xilinx
00029 -- \ \ \/ Version: 1.6
00030 -- \ \ Application : MIG
00031 -- / / Filename: ddr2_mem_tap_ctrl.vhd
00032 -- /___/ /\ Date Last Modified: Wed Jun 1 2005
00033 -- \ \ / \Date Created: Mon May 2 2005
00034 -- \___\/\___\
00035 --
00036 -- Device: Virtex-4
00037 -- Design Name: DDR2_V4
00038 -- Description :
00039 -------------------------------------------------------------------------------
00040
00041
00042 library ieee;
00043
00044 use ieee.std_logic_1164.all;
00045
00046 use ieee.std_logic_unsigned.all;
00047
00048 library unisim;
00049
00050 use unisim.vcomponents.all;
00051
00052
00053
00054
00055
00056
00057 entity ddr2_mem_tap_ctrl is
00058 port(
00059 CAL_CLK : in ;
00060 RESET : in ;
00061 RDY_STATUS : in ;
00062 DQS : in ;
00063 CTRL_DUMMYREAD_START : in ;
00064 DLYINC : out ;
00065 DLYCE : out ;
00066 DLYRST : out ;
00067 SEL_DONE : out ;
00068 VALID_DATA_TAP_COUNT : out ;
00069 DATA_TAP_COUNT : out (5 downto 0)
00070 );
00071 end ddr2_mem_tap_ctrl;
00072
00073
00074
00075
00076
00077
00078 architecture arch of ddr2_mem_tap_ctrl is
00079
00080 signal prev_dqs_level : ;
00081 signal dly_inc : ;
00082 signal dly_ce : ;
00083 signal dly_rst : ;
00084 signal transition : (1 downto 0);
00085 signal first_edge : ;
00086 signal second_edge : ;
00087 signal second_edge_r1 : ;
00088 signal second_edge_r2 : ;
00089 signal second_edge_r3 : ;
00090 signal transition_rst : ;
00091 signal sel_complete : ;
00092 signal tap_counter : (5 downto 0);
00093 signal first_edge_tap_count : (5 downto 0);
00094 signal second_edge_tap_count : (5 downto 0);
00095 signal pulse_width_tap_count : (5 downto 0);
00096 signal data_bit_tap_count : (5 downto 0);
00097 signal state : (2 downto 0);
00098 signal idelay_rst_idle : ;
00099 signal idelay_rst_idle_r1 : ;
00100 signal idelay_rst_idle_r2 : ;
00101 signal idelay_rst_idle_r3 : ;
00102 signal idelay_rst_idle_r4 : ;
00103 signal idelay_rst_idle_r5 : ;
00104 signal idelay_rst_idle_r6 : ;
00105 signal idelay_inc_idle : ;
00106 signal idelay_inc_idle_r1 : ;
00107 signal idelay_inc_idle_r2 : ;
00108 signal idelay_inc_idle_r3 : ;
00109 signal idelay_inc_idle_r4 : ;
00110 signal idelay_inc_idle_r5 : ;
00111 signal idelay_inc_idle_r6 : ;
00112 signal detect_edge_idle : ;
00113 signal detect_edge_idle_r1 : ;
00114 signal detect_edge_idle_r2 : ;
00115 signal detect_edge_idle_r3 : ;
00116 signal detect_edge_idle_r4 : ;
00117 signal detect_edge_idle_r5 : ;
00118 signal detect_edge_idle_r6 : ;
00119 signal flag : (3 downto 0);
00120 signal dly_after_first_cnt : (3 downto 0);
00121 signal pulse_center_tap_count : (5 downto 0);
00122 signal valid_data_count : ;
00123 signal data_count_valid : ;
00124 signal dly_after_first : (3 downto 0);
00125 signal curr_dqs_level : ;
00126 signal delay_sel_done : ;
00127 signal reset_int : ;
00128 signal first_edge_cnt : (2 downto 0);
00129
00130
00131 constant idelay_rst : (2 downto 0) := "000";
00132
00133 constant idle : (2 downto 0) := "001";
00134
00135 constant idelay_inc : (2 downto 0) := "010";
00136
00137 constant detect_edge : (2 downto 0) := "011";
00138
00139 begin
00140
00141 DLYINC <= dly_inc;
00142 DLYCE <= dly_ce;
00143 DLYRST <= dly_rst;
00144 SEL_DONE <= sel_complete;
00145 curr_dqs_level <= DQS;
00146 VALID_DATA_TAP_COUNT <= valid_data_count;
00147 DATA_TAP_COUNT <= data_bit_tap_count;
00148 data_count_valid <= '1' when (second_edge_r3 = '1') or (tap_counter = "111111") else '0';
00149 reset_int <= not(RDY_STATUS) or RESET;
00150 delay_sel_done <= '1' when ((second_edge = '1') or (tap_counter = "111111")) else
00151 '0' when (CTRL_DUMMYREAD_START = '0') else
00152 sel_complete;
00153 dly_after_first <= "1001" when ((transition = "01") and (first_edge = '0')) else --? 4'b1001 :
00154 (dly_after_first_cnt - '1') when ((dly_after_first_cnt /= "0000") and (dly_inc = '1')) else
00155 dly_after_first_cnt;
00156
00157
00158 process(CAL_CLK)
00159 begin
00160 if CAL_CLK'event and CAL_CLK = '1' then
00161 if reset_int = '1' then
00162 second_edge_r1 <= '0';
00163 second_edge_r2 <= '0';
00164 second_edge_r3 <= '0';
00165 idelay_rst_idle_r1 <= '0';
00166 idelay_rst_idle_r2 <= '0';
00167 idelay_rst_idle_r3 <= '0';
00168 idelay_rst_idle_r4 <= '0';
00169 idelay_rst_idle_r5 <= '0';
00170 idelay_rst_idle_r6 <= '0';
00171 idelay_inc_idle_r1 <= '0';
00172 idelay_inc_idle_r2 <= '0';
00173 idelay_inc_idle_r3 <= '0';
00174 idelay_inc_idle_r4 <= '0';
00175 idelay_inc_idle_r5 <= '0';
00176 idelay_inc_idle_r6 <= '0';
00177 detect_edge_idle_r1 <= '0';
00178 detect_edge_idle_r2 <= '0';
00179 detect_edge_idle_r3 <= '0';
00180 detect_edge_idle_r4 <= '0';
00181 detect_edge_idle_r5 <= '0';
00182 detect_edge_idle_r6 <= '0';
00183 valid_data_count <= '0';
00184 else
00185 second_edge_r1 <= second_edge;
00186 second_edge_r2 <= second_edge_r1;
00187 second_edge_r3 <= second_edge_r2;
00188 idelay_rst_idle_r1 <= idelay_rst_idle;
00189 idelay_rst_idle_r2 <= idelay_rst_idle_r1;
00190 idelay_rst_idle_r3 <= idelay_rst_idle_r2;
00191 idelay_rst_idle_r4 <= idelay_rst_idle_r3;
00192 idelay_rst_idle_r5 <= idelay_rst_idle_r4;
00193 idelay_rst_idle_r6 <= idelay_rst_idle_r5;
00194 idelay_inc_idle_r1 <= idelay_inc_idle;
00195 idelay_inc_idle_r2 <= idelay_inc_idle_r1;
00196 idelay_inc_idle_r3 <= idelay_inc_idle_r2;
00197 idelay_inc_idle_r4 <= idelay_inc_idle_r3;
00198 idelay_inc_idle_r5 <= idelay_inc_idle_r4;
00199 idelay_inc_idle_r6 <= idelay_inc_idle_r5;
00200 detect_edge_idle_r1 <= detect_edge_idle;
00201 detect_edge_idle_r2 <= detect_edge_idle_r1;
00202 detect_edge_idle_r3 <= detect_edge_idle_r2;
00203 detect_edge_idle_r4 <= detect_edge_idle_r3;
00204 detect_edge_idle_r5 <= detect_edge_idle_r4;
00205 detect_edge_idle_r6 <= detect_edge_idle_r5;
00206 valid_data_count <= data_count_valid;
00207 end if;
00208 end if;
00209 end process;
00210
00211
00212 process(CAL_CLK)
00213 begin
00214 if(CAL_CLK'event and CAL_CLK = '1') then
00215 if (reset_int = '1') then
00216 sel_complete <= '0';
00217 else
00218 sel_complete <= delay_sel_done;
00219 end if;
00220 end if;
00221 end process;
00222
00223
00224
00225 process(CAL_CLK)
00226 begin
00227 if(CAL_CLK'event and CAL_CLK = '1') then
00228 if (reset_int = '1') then
00229 dly_after_first_cnt <= "0000";
00230 else
00231 dly_after_first_cnt <= dly_after_first;
00232 end if;
00233 end if;
00234 end process;
00235
00236
00237 process(CAL_CLK)
00238 begin
00239 if(CAL_CLK'event and CAL_CLK = '1') then
00240 if ((reset_int = '1') or (tap_counter = "111111")) then
00241 tap_counter <= "000000";
00242 elsif (dly_inc = '1') then
00243 tap_counter <= tap_counter + '1';
00244 end if;
00245 end if;
00246 end process;
00247
00248
00249 process(CAL_CLK)
00250 begin
00251 if(CAL_CLK'event and CAL_CLK = '1') then
00252 if (reset_int = '1') then
00253 first_edge_tap_count <= "000000";
00254 first_edge_cnt <= "000";
00255 elsif ((transition = "01") and (first_edge = '0')) then
00256 first_edge_tap_count <= tap_counter;
00257 first_edge_cnt <= "110";
00258 elsif(dly_inc = '1' and first_edge = '1' and first_edge_cnt /= "000") then ---changed from first_edge_cnt != 3'b001 to first_edge_cnt != 3'b000 so that assignment of rising_edge only happens when first_edge_cnt == 001//////////////////////////////////
00259 first_edge_cnt <= first_edge_cnt - '1';
00260 end if;
00261 end if;
00262 end process;
00263
00264
00265 process(CAL_CLK)
00266 begin
00267 if(CAL_CLK'event and CAL_CLK = '1') then
00268 if (reset_int = '1') then
00269 second_edge_tap_count <= "000000";
00270 elsif ((transition = "10") and (second_edge = '0')) then
00271 second_edge_tap_count <= tap_counter;
00272 end if;
00273 end if;
00274 end process;
00275
00276
00277 process(CAL_CLK)
00278 begin
00279 if(CAL_CLK'event and CAL_CLK = '1') then
00280 if (reset_int = '1') then
00281 pulse_width_tap_count <= "000000";
00282 elsif (second_edge_r1 = '1') then
00283 pulse_width_tap_count <= (second_edge_tap_count - first_edge_tap_count);
00284 end if;
00285 end if;
00286 end process;
00287
00288
00289 process(CAL_CLK)
00290 begin
00291 if(CAL_CLK'event and CAL_CLK = '1') then
00292 if (reset_int = '1') then
00293 pulse_center_tap_count <= "000000";
00294 elsif (second_edge_r2 = '1') then
00295 pulse_center_tap_count <= '0' & pulse_width_tap_count(5 downto 1); -- Shift right to divide by 2 and find pulse center
00296 end if;
00297 end if;
00298 end process;
00299
00300
00301 process(CAL_CLK)
00302 begin
00303 if(CAL_CLK'event and CAL_CLK = '1') then
00304 if (reset_int = '1') then
00305 data_bit_tap_count <= "000000";
00306 elsif (second_edge_r3 = '1') then -- 2 edges detected
00307 data_bit_tap_count <= first_edge_tap_count + pulse_center_tap_count; --+ "000100";
00308 elsif ((transition = "01") and ((tap_counter = "111111"))) then -- Only 1 edge detected
00309 --data_bit_tap_count <= first_edge_tap_count + "010000";
00310 if (first_edge_tap_count(5) = '0') then
00311 data_bit_tap_count <= first_edge_tap_count + "010000";
00312 else
00313 data_bit_tap_count <= first_edge_tap_count - "010000";
00314 end if;
00315 elsif ((transition = "00") and ((tap_counter = "111111"))) then -- No edges detected
00316 data_bit_tap_count <= "100000";
00317 end if;
00318 end if;
00319 end process;
00320
00321
00322
00323
00324 process(CAL_CLK)
00325 begin
00326 if CAL_CLK'event and CAL_CLK = '1' then
00327 if (reset_int = '1') then
00328 flag <= (others => '0');
00329 elsif (detect_edge_idle_r3 = '1' or idelay_inc_idle_r3 = '1' or idelay_rst_idle_r3 = '1') then
00330 if (curr_dqs_level /= prev_dqs_level) then
00331 flag(0) <= '0';
00332 else
00333 flag(0) <= '1';
00334 end if;
00335 elsif (detect_edge_idle_r4 = '1' or idelay_inc_idle_r4 = '1' or idelay_rst_idle_r4 = '1') then
00336 if (curr_dqs_level /= prev_dqs_level) then
00337 flag(1) <= '0';
00338 else
00339 flag(1) <= '1';
00340 end if;
00341 elsif (detect_edge_idle_r5 = '1' or idelay_inc_idle_r5 = '1' or idelay_rst_idle_r5 = '1') then
00342 if (curr_dqs_level /= prev_dqs_level) then
00343 flag(2) <= '0';
00344 else
00345 flag(2) <= '1';
00346 end if;
00347 elsif (detect_edge_idle_r6 = '1' or idelay_inc_idle_r6 = '1' or idelay_rst_idle_r6 = '1') then
00348 if (curr_dqs_level /= prev_dqs_level) then
00349 flag(3) <= '0';
00350 else
00351 flag(3) <= '1';
00352 end if;
00353
00354 end if;
00355 end if;
00356 end process;
00357
00358
00359 process(CAL_CLK)
00360 begin
00361 if(CAL_CLK'event and CAL_CLK = '1') then
00362 if (reset_int = '1') then
00363 transition(1 downto 0) <= "00";
00364 elsif ((dly_after_first_cnt = "0000") and (state = detect_edge) and ((flag = X"0") or (flag = X"F"))) then
00365 if ((curr_dqs_level /= prev_dqs_level) and (transition_rst = '0') and (tap_counter > "000000")) then
00366 transition <= transition + '1';
00367 end if;
00368 elsif (transition_rst = '1') then
00369 transition <= "00";
00370 else
00371 transition <= transition;
00372 end if;
00373 end if;
00374 end process;
00375
00376
00377 process(CAL_CLK)
00378 begin
00379 if(CAL_CLK'event and CAL_CLK = '1') then
00380 if (reset_int = '1') then
00381 transition_rst <= '0';
00382 first_edge <= '0';
00383 second_edge <= '0';
00384 else
00385 case transition is
00386 when "01" =>
00387 first_edge <= '1';
00388 when "10" =>
00389 if (transition_rst = '1') then
00390 second_edge <= '0';
00391 transition_rst <= '0';
00392 else
00393 second_edge <= '1';
00394 transition_rst <= '1';
00395 end if;
00396 when others =>
00397 first_edge <= '0';
00398 second_edge <= '0';
00399 end case;
00400 end if;
00401 end if;
00402 end process;
00403
00404
00405 process(CAL_CLK)
00406 begin
00407 if(CAL_CLK'event and CAL_CLK = '1') then
00408 if (reset_int = '1') then -- DQS IDELAY in reset
00409 dly_rst <= '1';
00410 dly_ce <= '0';
00411 dly_inc <= '0';
00412 idelay_rst_idle <= '0';
00413 detect_edge_idle <= '0';
00414 idelay_inc_idle <= '0';
00415 prev_dqs_level <= curr_dqs_level;
00416 state(2 downto 0) <= idelay_rst;
00417 elsif ((CTRL_DUMMYREAD_START = '1') and (sel_complete = '0')) then
00418 case state is
00419 when "000" => -- idelay_rst
00420 dly_rst <= '1';
00421 dly_ce <= '0';
00422 dly_inc <= '0';
00423 idelay_rst_idle <= '1';
00424 state(2 downto 0) <= idle;
00425 when "001" => -- idle
00426 dly_rst <= '0';
00427 dly_ce <= '0';
00428 dly_inc <= '0';
00429 idelay_rst_idle <= '0';
00430 detect_edge_idle <= '0';
00431 idelay_inc_idle <= '0';
00432 if (idelay_rst_idle_r5 = '1') then
00433 state(2 downto 0) <= idelay_inc;
00434 elsif ((idelay_inc_idle_r6 = '1') or ((detect_edge_idle_r6 = '1') and (second_edge_r2 = '0') and (tap_counter /= "111111"))) then
00435 state(2 downto 0) <= detect_edge;
00436 else
00437 state(2 downto 0) <= idle;
00438 end if;
00439 when "010" => -- idelay_inc
00440 dly_rst <= '0';
00441 dly_ce <= '1';
00442 dly_inc <= '1';
00443 idelay_inc_idle <= '1';
00444 state(2 downto 0) <= idle;
00445 if((flag(3 downto 0) = X"0") or (flag(3 downto 0) = X"F")) then
00446 prev_dqs_level <= curr_dqs_level;
00447 else
00448 prev_dqs_level <= prev_dqs_level;
00449 end if;
00450
00451 when "011" => -- detect_edge
00452 dly_rst <= '0';
00453 dly_ce <= '1';
00454 dly_inc <= '1';
00455 detect_edge_idle <= '1';
00456 state(2 downto 0) <= idle;
00457 if((flag(3 downto 0) = X"0") or (flag(3 downto 0) = X"F")) then
00458 prev_dqs_level <= curr_dqs_level;
00459 else
00460 prev_dqs_level <= prev_dqs_level;
00461 end if;
00462 when others =>
00463 dly_rst <= '0';
00464 dly_ce <= '0';
00465 dly_inc <= '0';
00466 idelay_rst_idle <= '0';
00467 detect_edge_idle <= '0';
00468 idelay_inc_idle <= '0';
00469 prev_dqs_level <= curr_dqs_level;
00470 state(2 downto 0) <= idle;
00471 end case;
00472 else
00473 dly_rst <= '0';
00474 dly_ce <= '0';
00475 dly_inc <= '0';
00476 idelay_rst_idle <= '0';
00477 detect_edge_idle <= '0';
00478 idelay_inc_idle <= '0';
00479 prev_dqs_level <= curr_dqs_level;
00480 state <= idelay_rst;
00481 end if;
00482 end if;
00483 end process;
00484
00485 end arch;