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/ddr/mem_interface_top_tap_ctrl_0.vhd,v $ *
00015 --* $Revision: 1.4.2.3 $ *
00016 --* $Name: dev $ *
00017 --* $Author: mniegl $ *
00018 --* $Date: 2008/11/03 17:57:44 $ *
00019 --* *
00020 --**************************************************************
00021 -------------------------------------------------------------------------------
00022 -- Copyright (c) 2005 Xilinx, Inc.
00023 -- This design is confidential and proprietary of Xilinx, All Rights Reserved.
00024 -------------------------------------------------------------------------------
00025 -- ____ ____
00026 -- / /\/ /
00027 -- /___/ \ / Vendor: Xilinx
00028 -- \ \ \/ Version: 1.6
00029 -- \ \ Application : MIG
00030 -- / / Filename: mem_interface_top_tap_ctrl.vhd
00031 -- /___/ /\ Date Last Modified: Wed Jun 1 2005
00032 -- \ \ / \Date Created: Mon May 2 2005
00033 -- \___\/\___\
00034 -- Device: Virtex-4
00035 -- Design Name: DDR1_SDRAM
00036 -- Description: The tap control logic which claculates the relation between the
00037 -- FPGA clock and the dqs from memory. It delays the dqs so as to detect the edges
00038 -- of the dqs and then calculates the mid point so that the data can be registered
00039 -- properly.
00040 -------------------------------------------------------------------------------
00041
00042
00043 library ieee;
00044
00045 use ieee.std_logic_1164.all;
00046
00047 use ieee.std_logic_unsigned.all;
00048
00049 library unisim;
00050
00051 use unisim.vcomponents.all;
00052
00053 entity mem_interface_top_tap_ctrl is
00054 port(CLK : in ;
00055 RESET : in ;
00056 RDY_STATUS : in ;
00057 DQS : in ;
00058 CTRL_DUMMYREAD_START : in ;
00059 DLYINC : out ;
00060 DLYCE : out ;
00061 DLYRST : out ;
00062 SEL_DONE : out ;
00063 VALID_DATA_TAP_COUNT : out ;
00064 DATA_TAP_COUNT : out (5 downto 0)
00065 );
00066 end mem_interface_top_tap_ctrl;
00067
00068 architecture arch of mem_interface_top_tap_ctrl is
00069
00070 signal prev_dqs_level : ;
00071 signal dly_inc : ;
00072 signal dly_ce : ;
00073 signal dly_rst : ;
00074 signal transition : (1 downto 0);
00075 signal first_edge : ;
00076 signal second_edge : ;
00077 signal second_edge_r1 : ;
00078 signal second_edge_r2 : ;
00079 signal second_edge_r3 : ;
00080 signal transition_rst : ;
00081 signal sel_complete : ;
00082 signal tap_counter : (5 downto 0);
00083 signal first_edge_tap_count : (5 downto 0);
00084 signal second_edge_tap_count : (5 downto 0);
00085 signal pulse_width_tap_count : (5 downto 0);
00086 signal data_bit_tap_count : (5 downto 0);
00087 signal state : (2 downto 0);
00088 signal idelay_rst_idle : ;
00089 signal idelay_rst_idle_r1 : ;
00090 signal idelay_rst_idle_r2 : ;
00091 signal idelay_rst_idle_r3 : ;
00092 signal idelay_rst_idle_r4 : ;
00093 signal idelay_rst_idle_r5 : ;
00094 signal idelay_rst_idle_r6 : ;
00095 signal idelay_inc_idle : ;
00096 signal idelay_inc_idle_r1 : ;
00097 signal idelay_inc_idle_r2 : ;
00098 signal idelay_inc_idle_r3 : ;
00099 signal idelay_inc_idle_r4 : ;
00100 signal idelay_inc_idle_r5 : ;
00101 signal idelay_inc_idle_r6 : ;
00102 signal detect_edge_idle : ;
00103 signal detect_edge_idle_r1 : ;
00104 signal detect_edge_idle_r2 : ;
00105 signal detect_edge_idle_r3 : ;
00106 signal detect_edge_idle_r4 : ;
00107 signal detect_edge_idle_r5 : ;
00108 signal detect_edge_idle_r6 : ;
00109 signal flag : (3 downto 0);
00110 signal dly_after_first_cnt : (3 downto 0);
00111 signal pulse_center_tap_count : (5 downto 0);
00112 signal valid_data_count : ;
00113 signal data_count_valid : ;
00114 signal dly_after_first : (3 downto 0);
00115 signal curr_dqs_level : ;
00116 signal delay_sel_done : ;
00117 signal reset_int : ;
00118 signal first_edge_cnt : (2 downto 0);
00119 constant idelay_rst : (2 downto 0) := "000";
00120 constant idle : (2 downto 0) := "001";
00121 constant idelay_inc : (2 downto 0) := "010";
00122 constant detect_edge : (2 downto 0) := "011";
00123
00124
00125
00126 begin
00127
00128 DLYINC <= dly_inc;
00129 DLYCE <= dly_ce;
00130 DLYRST <= dly_rst;
00131 SEL_DONE <= sel_complete;
00132 VALID_DATA_TAP_COUNT <= valid_data_count;
00133 DATA_TAP_COUNT <= data_bit_tap_count;
00134
00135 data_count_valid <= '1' when (second_edge_r3 = '1') or (tap_counter = "111111") else '0';
00136 reset_int <= not(RDY_STATUS) or RESET;
00137
00138 delay_sel_done <= '1' when ((second_edge = '1') or (tap_counter = "111111")) else
00139 '0' when (CTRL_DUMMYREAD_START = '0') else
00140 sel_complete;
00141
00142 dly_after_first <= "1001" when ((transition = "01") and (first_edge = '0')) else --? 4'b1001 :
00143 (dly_after_first_cnt - '1') when ((dly_after_first_cnt /= "0000") and (dly_inc = '1')) else
00144 dly_after_first_cnt;
00145
00146 curr_dqs_level <= DQS;
00147
00148 -- Shift registers for controls
00149 process(CLK)
00150 begin
00151 if CLK'event and CLK = '1' then
00152 if reset_int = '1' then
00153 second_edge_r1 <= '0';
00154 second_edge_r2 <= '0';
00155 second_edge_r3 <= '0';
00156 idelay_rst_idle_r1 <= '0';
00157 idelay_rst_idle_r2 <= '0';
00158 idelay_rst_idle_r3 <= '0';
00159 idelay_rst_idle_r4 <= '0';
00160 idelay_rst_idle_r5 <= '0';
00161 idelay_rst_idle_r6 <= '0';
00162
00163 idelay_inc_idle_r1 <= '0';
00164 idelay_inc_idle_r2 <= '0';
00165 idelay_inc_idle_r3 <= '0';
00166 idelay_inc_idle_r4 <= '0';
00167 idelay_inc_idle_r5 <= '0';
00168 idelay_inc_idle_r6 <= '0';
00169
00170 detect_edge_idle_r1 <= '0';
00171 detect_edge_idle_r2 <= '0';
00172 detect_edge_idle_r3 <= '0';
00173 detect_edge_idle_r4 <= '0';
00174 detect_edge_idle_r5 <= '0';
00175 detect_edge_idle_r6 <= '0';
00176
00177 valid_data_count <= '0';
00178 else
00179 second_edge_r1 <= second_edge;
00180 second_edge_r2 <= second_edge_r1;
00181 second_edge_r3 <= second_edge_r2;
00182 idelay_rst_idle_r1 <= idelay_rst_idle;
00183 idelay_rst_idle_r2 <= idelay_rst_idle_r1;
00184 idelay_rst_idle_r3 <= idelay_rst_idle_r2;
00185 idelay_rst_idle_r4 <= idelay_rst_idle_r3;
00186 idelay_rst_idle_r5 <= idelay_rst_idle_r4;
00187 idelay_rst_idle_r6 <= idelay_rst_idle_r5;
00188
00189 idelay_inc_idle_r1 <= idelay_inc_idle;
00190 idelay_inc_idle_r2 <= idelay_inc_idle_r1;
00191 idelay_inc_idle_r3 <= idelay_inc_idle_r2;
00192 idelay_inc_idle_r4 <= idelay_inc_idle_r3;
00193 idelay_inc_idle_r5 <= idelay_inc_idle_r4;
00194 idelay_inc_idle_r6 <= idelay_inc_idle_r5;
00195
00196
00197 detect_edge_idle_r1 <= detect_edge_idle;
00198 detect_edge_idle_r2 <= detect_edge_idle_r1;
00199 detect_edge_idle_r3 <= detect_edge_idle_r2;
00200 detect_edge_idle_r4 <= detect_edge_idle_r3;
00201 detect_edge_idle_r5 <= detect_edge_idle_r4;
00202 detect_edge_idle_r6 <= detect_edge_idle_r5;
00203
00204 valid_data_count <= data_count_valid;
00205 end if;
00206 end if;
00207 end process;
00208
00209 -- Tap Delay Selection Complete for Data bus associated with a DQS
00210 process(CLK)
00211 begin
00212 if(CLK'event and CLK = '1') then
00213 if (reset_int = '1') then
00214 sel_complete <= '0';
00215 else
00216 sel_complete <= delay_sel_done;
00217 end if;
00218 end if;
00219 end process;
00220
00221
00222 -- Start detection of second transition only after 10 taps from first transition
00223 process(CLK)
00224 begin
00225 if(CLK'event and CLK = '1') then
00226 if (reset_int = '1') then
00227 dly_after_first_cnt <= "0000";
00228 else
00229 dly_after_first_cnt <= dly_after_first;
00230 end if;
00231 end if;
00232 end process;
00233
00234
00235 -- Tap Counter
00236 process(CLK)
00237 begin
00238 if(CLK'event and CLK = '1') then
00239 if ((reset_int = '1') or (tap_counter = "111111")) then
00240 tap_counter <= "000000";
00241 elsif (dly_inc = '1') then
00242 tap_counter <= tap_counter + '1';
00243 end if;
00244 end if;
00245 end process;
00246
00247 -- Tap value for Data IDELAY circuit
00248 process(CLK)
00249 begin
00250 if(CLK'event and CLK = '1') then
00251 if (reset_int = '1') then
00252 first_edge_tap_count <= "000000";
00253 first_edge_cnt <= "000";
00254 elsif ((transition = "01") and (first_edge = '0')) then
00255 first_edge_tap_count <= tap_counter;
00256 first_edge_cnt <= "110";
00257 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//////////////////////////////////
00258 first_edge_cnt <= first_edge_cnt - '1';
00259 end if;
00260 end if;
00261 end process;
00262
00263 process(CLK)
00264 begin
00265 if(CLK'event and CLK = '1') then
00266 if (reset_int = '1') then
00267 second_edge_tap_count <= "000000";
00268 elsif ((transition = "10") and (second_edge = '0')) then
00269 second_edge_tap_count <= tap_counter;
00270 end if;
00271 end if;
00272 end process;
00273
00274
00275 process(CLK)
00276 begin
00277 if(CLK'event and CLK = '1') then
00278 if (reset_int = '1') then
00279 pulse_width_tap_count <= "000000";
00280 elsif (second_edge_r1 = '1') then
00281 pulse_width_tap_count <= (second_edge_tap_count - first_edge_tap_count);
00282 end if;
00283 end if;
00284 end process;
00285
00286
00287 process(CLK)
00288 begin
00289 if(CLK'event and CLK = '1') then
00290 if (reset_int = '1') then
00291 pulse_center_tap_count <= "000000";
00292 elsif (second_edge_r2 = '1') then
00293 pulse_center_tap_count <= '0' & pulse_width_tap_count(5 downto 1); -- Shift right to divide by 2 and find pulse center
00294 end if;
00295 end if;
00296 end process;
00297
00298
00299 process(CLK)
00300 begin
00301 if(CLK'event and CLK = '1') then
00302 if (reset_int = '1') then
00303 data_bit_tap_count <= "000000";
00304 elsif (second_edge_r3 = '1') then -- 2 edges detected
00305 data_bit_tap_count <= first_edge_tap_count + pulse_center_tap_count; --+ "000100";
00306 elsif ((transition = "01") and ((tap_counter = "111111"))) then -- Only 1 edge detected
00307 if (first_edge_tap_count(5) = '0') then
00308 data_bit_tap_count <= first_edge_tap_count + "010000";
00309 else
00310 data_bit_tap_count <= first_edge_tap_count - "010000";
00311 end if;
00312 elsif ((transition = "00") and ((tap_counter = "111111"))) then -- No edges detected
00313 data_bit_tap_count <= "100000";
00314 end if;
00315 end if;
00316 end process;
00317
00318
00319 -- Logic required to determine whether the registered DQS is on the edge of meeting setup time in the FPGA clock domain.
00320 -- If DQS is on the edge, then the vector 'flag' will not be "1111" or "0000" and edge detection will not be executed.
00321 -- If DQS is not on the edge, then the vector 'flag' will be "1111" or "0000" and edge detection will be executed.
00322
00323 process(CLK)
00324 begin
00325 if CLK'event and CLK = '1' then
00326 if (reset_int = '1') then
00327 flag <= (others => '0');
00328 elsif (detect_edge_idle_r3 = '1' or idelay_inc_idle_r3 = '1' or idelay_rst_idle_r3 = '1') then
00329 if (curr_dqs_level /= prev_dqs_level) then
00330 flag(0) <= '0';
00331 else
00332 flag(0) <= '1';
00333 end if;
00334 elsif (detect_edge_idle_r4 = '1' or idelay_inc_idle_r4 = '1' or idelay_rst_idle_r4 = '1') then
00335 if (curr_dqs_level /= prev_dqs_level) then
00336 flag(1) <= '0';
00337 else
00338 flag(1) <= '1';
00339 end if;
00340 elsif (detect_edge_idle_r5 = '1' or idelay_inc_idle_r5 = '1' or idelay_rst_idle_r5 = '1') then
00341 if (curr_dqs_level /= prev_dqs_level) then
00342 flag(2) <= '0';
00343 else
00344 flag(2) <= '1';
00345 end if;
00346 elsif (detect_edge_idle_r6 = '1' or idelay_inc_idle_r6 = '1' or idelay_rst_idle_r6 = '1') then
00347 if (curr_dqs_level /= prev_dqs_level) then
00348 flag(3) <= '0';
00349 else
00350 flag(3) <= '1';
00351 end if;
00352
00353 end if;
00354 end if;
00355 end process;
00356
00357
00358 -- First and second edge assignment logic
00359 process(CLK)
00360 begin
00361 if(CLK'event and 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(CLK)
00378 begin
00379 if(CLK'event and 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
00389 when "10" =>
00390 if (transition_rst = '1') then
00391 second_edge <= '0';
00392 transition_rst <= '0';
00393 else
00394 second_edge <= '1';
00395 transition_rst <= '1';
00396 end if;
00397 when others =>
00398 first_edge <= '0';
00399 second_edge <= '0';
00400 end case;
00401 end if;
00402 end if;
00403 end process;
00404
00405 -- State Machine for edge detection and midpoint determination
00406 process(CLK)
00407 begin
00408 if(CLK'event and CLK = '1') then
00409 if (reset_int = '1') then -- DQS IDELAY in reset
00410 dly_rst <= '1';
00411 dly_ce <= '0';
00412 dly_inc <= '0';
00413 idelay_rst_idle <= '0';
00414 detect_edge_idle <= '0';
00415 idelay_inc_idle <= '0';
00416 prev_dqs_level <= curr_dqs_level;
00417 state(2 downto 0) <= idelay_rst;
00418 elsif ((CTRL_DUMMYREAD_START = '1') and (sel_complete = '0')) then
00419 case state is
00420 when "000" => -- idelay_rst
00421 dly_rst <= '1';
00422 dly_ce <= '0';
00423 dly_inc <= '0';
00424 idelay_rst_idle <= '1';
00425 state(2 downto 0) <= idle;
00426 when "001" => -- idle
00427 dly_rst <= '0';
00428 dly_ce <= '0';
00429 dly_inc <= '0';
00430 idelay_rst_idle <= '0';
00431 detect_edge_idle <= '0';
00432 idelay_inc_idle <= '0';
00433 if (idelay_rst_idle_r5 = '1') then
00434 state(2 downto 0) <= idelay_inc;
00435 elsif ((idelay_inc_idle_r6 = '1') or ((detect_edge_idle_r6 = '1') and (second_edge_r2 = '0') and (tap_counter /= "111111"))) then
00436 state(2 downto 0) <= detect_edge;
00437 else
00438 state(2 downto 0) <= idle;
00439 end if;
00440 when "010" => -- idelay_inc
00441 dly_rst <= '0';
00442 dly_ce <= '1';
00443 dly_inc <= '1';
00444 idelay_inc_idle <= '1';
00445 state(2 downto 0) <= idle;
00446 if((flag(3 downto 0) = X"0") or (flag(3 downto 0) = X"F")) then
00447 prev_dqs_level <= curr_dqs_level;
00448 else
00449 prev_dqs_level <= prev_dqs_level;
00450 end if;
00451
00452 when "011" => -- detect_edge
00453 dly_rst <= '0';
00454 dly_ce <= '1';
00455 dly_inc <= '1';
00456 detect_edge_idle <= '1';
00457 state(2 downto 0) <= idle;
00458 if((flag(3 downto 0) = X"0") or (flag(3 downto 0) = X"F")) then
00459 prev_dqs_level <= curr_dqs_level;
00460 else
00461 prev_dqs_level <= prev_dqs_level;
00462 end if;
00463 when others =>
00464 dly_rst <= '0';
00465 dly_ce <= '0';
00466 dly_inc <= '0';
00467 idelay_rst_idle <= '0';
00468 detect_edge_idle <= '0';
00469 idelay_inc_idle <= '0';
00470 prev_dqs_level <= curr_dqs_level;
00471 state(2 downto 0) <= idle;
00472 end case;
00473 else
00474 dly_rst <= '0';
00475 dly_ce <= '0';
00476 dly_inc <= '0';
00477 idelay_rst_idle <= '0';
00478 detect_edge_idle <= '0';
00479 idelay_inc_idle <= '0';
00480 prev_dqs_level <= curr_dqs_level;
00481 state <= idelay_rst;
00482 end if;
00483 end if;
00484 end process;
00485
00486 end arch;