?? phy_rden_align.vhd
字號:
-------------------------------------------------------------------------------
-- Copyright (c) 2006 Xilinx, Inc.
-- This design is confidential and proprietary of Xilinx, All Rights Reserved.
-------------------------------------------------------------------------------
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor: Xilinx
-- \ \ \/ Version: 1.1
-- \ \ Filename: phy_rden_align.vhd
-- / / Date Last Modified: 5/10/06
-- /___/ /\ Date Created:
-- \ \ / \
-- \___\/\___\
--
--Device: Virtex-5
--Purpose: read enable calibration logic. Also delays read
-- captured read data (aka read data "FIFO").
--Reference:
-- XAPP851
--Revision History:
-- Rev 0.1 - Created. Author: Toshihiko Moriyama. 11/17/05
-- Rev 1.0 - Internal release. Author: Toshihiko Moriyama. 4/29/06.
-- Rev 1.1 - External release. Added header. 5/10/06.
-------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
library work;
use work.ddr1_parameters.all;
library unisim ;
use unisim.vcomponents.all;
entity phy_rden_align is
port (
rst : in std_logic;
clk0 : in std_logic;
rd_en_i : in std_logic; -- From controller
rd_data_i : in std_logic_vector(dq_per_dqs*2 - 1 downto 0); -- From the read data capture logic
rd_data_o : out std_logic_vector(dq_per_dqs*2 - 1 downto 0); -- To UI
rd_lat_o : out std_logic_vector(5 downto 0); -- To UI
latency : in std_logic_vector(3 downto 0); -- Fixed latency
calib_start : in std_logic; -- From controller
calib_done : out std_logic; -- To controller. When 1, second calibration done
error : out std_logic
);
end phy_rden_align;
-----------------------------------------------
architecture rtl of phy_rden_align is
TYPE ALIGNSTATE_TYPE is (
WAIT_ST, -- wait until data is valid
IDLE_ST,
RDEN0_ST,
RDEN1_ST,
RUN_ST,
ERRCNT_ST,
ERROR_ST
);
signal state_c : ALIGNSTATE_TYPE;
signal state_n : ALIGNSTATE_TYPE;
signal data_srl : std_logic_vector(dq_per_dqs*2 - 1 downto 0);
signal data_dly : std_logic_vector(3 downto 0);
signal rden_to_data : std_logic_vector(3 downto 0);
signal alignCnt : std_logic_vector(2 downto 0);
signal rd_en_dlycnt : std_logic_vector(3 downto 0);
signal rd_en_dlycntLast : std_logic_vector(3 downto 0);
signal rden_aligned : std_logic;
signal errCnt : std_logic_vector(3 downto 0);
constant TRAIN_PTN0 : std_logic_vector(7 downto 0) := X"A5";
constant TRAIN_PTN1 : std_logic_vector(7 downto 0) := X"3C";
signal LOGIC_0 : std_logic;
signal LOGIC_1 : std_logic;
begin
LOGIC_0 <= '0';
LOGIC_1 <= '1';
process( clk0 )
begin
if clk0'event and clk0='1' then
if rst='1' then
data_dly <= (others => '0');
else
if latency = rden_to_data then
data_dly <= (others => '0');
else
data_dly <= latency - rden_to_data - 1;
end if;
end if;
end if;
end process;
------------------------------------------------------------------
G_RDDATA : for I in 0 to dq_per_dqs*2 - 1 generate
SRL16_RDDATA : SRL16
generic map (
INIT => X"0000")
port map (
Q => data_srl(I),
A0 => data_dly(0),
A1 => data_dly(1),
A2 => data_dly(2),
A3 => data_dly(3),
CLK => clk0,
D => rd_data_i(I)
);
end generate;
rd_data_o <= data_srl when latency /= rden_to_data else rd_data_i;
calib_done <= rden_aligned;
P_ALIGN_NEXT : process( clk0 )
begin
if clk0'event and clk0='1' then
if rst='1' then
state_c <= WAIT_ST;
else
state_c <= state_n;
end if;
end if;
end process;
-------------------
-- STATE MACHINE --
-------------------
P_ALIGN_ST : process(rst, state_c, rd_en_i, calib_start, rd_data_i, alignCnt, rd_en_dlycnt, errCnt )
begin
if rst='1' then
state_n <= WAIT_ST;
else
case state_c is
when WAIT_ST =>
if calib_start = '1' then
state_n <= IDLE_ST;
else
state_n <= WAIT_ST;
end if;
when IDLE_ST =>
if alignCnt=3 then
state_n <= RUN_ST;
elsif rd_en_i = '1' then
state_n <= RDEN0_ST;
else
state_n <= IDLE_ST;
end if;
when RDEN0_ST =>
if (rd_data_i(3 downto 0) = TRAIN_PTN0(3 downto 0)) and
(rd_data_i(dq_per_dqs + 3 downto dq_per_dqs) = TRAIN_PTN0(7 downto 4)) then
state_n <= RDEN1_ST;
elsif rd_en_dlycnt = X"F" then
state_n <= ERRCNT_ST;
else
state_n <= RDEN0_ST;
end if;
when RDEN1_ST =>
state_n <= IDLE_ST;
when RUN_ST =>
state_n <= RUN_ST;
when ERRCNT_ST =>
if errCnt = X"F" then
state_n <= ERROR_ST;
else
state_n <= IDLE_ST;
end if;
when ERROR_ST =>
state_n <= ERROR_ST;
when others =>
state_n <= WAIT_ST;
end case;
end if;
end process;
-- delay increment
P_ALIGN : process( clk0 )
begin
if clk0'event and clk0='1' then
if rst='1' then
alignCnt <= (others => '0');
rd_en_dlycnt <= (others => '0');
rd_en_dlycntLast <= (others => '0');
rden_to_data <= (others => '0');
else
case state_c is
when WAIT_ST =>
alignCnt <= (others => '0');
rd_en_dlycnt <= (others => '0');
rd_en_dlycntLast <= (others => '0');
rden_to_data <= (others => '0');
when IDLE_ST =>
alignCnt <= alignCnt;
rd_en_dlycnt <= (others => '0');
rd_en_dlycntLast <= rd_en_dlycntLast;
rden_to_data <= (others => '0');
when RDEN0_ST =>
alignCnt <= alignCnt;
rd_en_dlycnt <= rd_en_dlycnt + 1;
rd_en_dlycntLast <= rd_en_dlycntLast;
rden_to_data <= (others => '0');
when RDEN1_ST =>
if (rd_data_i(3 downto 0) = TRAIN_PTN1(3 downto 0)) and
(rd_data_i(dq_per_dqs + 3 downto dq_per_dqs) = TRAIN_PTN1(7 downto 4)) and
(rd_en_dlycntLast = rd_en_dlycnt) then
alignCnt <= alignCnt + 1;
else
alignCnt <= (others => '0');
end if;
rd_en_dlycnt <= rd_en_dlycnt;
rd_en_dlycntLast <= rd_en_dlycnt;
rden_to_data <= (others => '0');
when RUN_ST =>
alignCnt <= (others => '0');
rd_en_dlycnt <= rd_en_dlycnt;
rd_en_dlycntLast <= rd_en_dlycntLast;
rden_to_data <= rd_en_dlycntLast;
when others =>
alignCnt <= (others => '0');
rd_en_dlycnt <= (others => '0');
rd_en_dlycntLast <= (others => '0');
rden_to_data <= (others => '0');
end case;
end if;
end if;
end process;
-- output this module's read data latency from rden
P_RD_LAT : process( clk0 )
begin
if clk0'event and clk0='1' then
if rst = '1' then
rd_lat_o <= (others => '0');
else
case rden_to_data is
when "0011" => -- 3
rd_lat_o <= "000001";
when "0100" => -- 4
rd_lat_o <= "000010";
when "0101" => -- 5
rd_lat_o <= "000100";
when "0111" => -- 6
rd_lat_o <= "001000";
when "1000" => -- 7
rd_lat_o <= "010000";
when "1001" => -- 8
rd_lat_o <= "100000";
when others =>
rd_lat_o <= (others => '0');
end case;
end if;
end if;
end process;
P_DONE : process( clk0 )
begin
if clk0'event and clk0='1' then
if rst='1' then
rden_aligned <= '0';
else
case state_c is
when RUN_ST =>
rden_aligned <= '1';
when others =>
rden_aligned <= '0';
end case;
end if;
end if;
end process;
-- error may occur due to bad signal integrity
P_ERROR : process( clk0 )
begin
if clk0'event and clk0='1' then
if rst='1' then
errCnt <= (others => '0');
error <= '0';
else
case state_c is
when ERRCNT_ST =>
errCnt <= errCnt + 1;
error <= '1';
when ERROR_ST =>
errCnt <= (others => '0');
error <= '1';
when others =>
errCnt <= (others => '0');
error <= '0';
end case;
end if;
end if;
end process;
end rtl;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -