⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 phy_init.vhd

📁 The xapp851.zip archive includes the following subdirectories. The specific contents of each subdi
💻 VHD
字号:
-------------------------------------------------------------------------------
-- Copyright (c) 2006 Xilinx, Inc.
-- This design is confidential and proprietary of Xilinx, All Rights Reserved.
-------------------------------------------------------------------------------
--   ____  ____
--  /   /\/   /
-- /___/  \  /   Vendor: Xilinx
-- \   \   \/    Version: 1.1
--  \   \        Filename: phy_init.vhd
--  /   /        Date Last Modified: 5/10/06
-- /___/   /\    Date Created:
-- \   \  /  \
--  \___\/\___\
-- 
--Device: Virtex-5
--Purpose: DDR SDRAM memory initialization state machine
--Reference:
--    XAPP851
--Revision History:
--    Rev 0.1 - Created. Author: Toshihiko Moriyama. 1/04/06.
--    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;

entity phy_init is
port(

	rst				: in	std_logic;
	clk0			: in	std_logic;

	-- from/to memory
	-- During initialization, PHY controller issues commands
	cke_o			: out	std_logic;
	cs_n_o			: out	std_logic;
	ras_n_o			: out	std_logic;
	cas_n_o			: out	std_logic;
	we_n_o			: out	std_logic;
	addr_o			: out	std_logic_vector(row_address - 1 downto 0);
	bank_o			: out	std_logic_vector(bank_address - 1 downto 0);

	-- internal interface
	init_done		: out	std_logic
);
end phy_init;

-----------------------------------------------
architecture rtl of phy_init is

	TYPE DDR1_TYPE is (
	INIT_ST,
	WAIT200US_ST,		-- wait 200us
	CKEHIGH_ST,			-- Issue NOP and set CLE ot high
	CKEHIGH_WAIT_ST,	-- Wait
	PRECHARGE0_ST,		-- Precharge All command
	PRECHARGE0_WAIT_ST,	-- Wait
	LMR0_ST,			-- Load mode register commnad (Extended Mode Register)
	LMR0_WAIT_ST,		-- Wait
	LMR1_ST,			-- Load mode register commnad (Base Mode Register setting with DDL Reset)
	LMR1_WAIT_ST,		-- Wait
	PRECHARGE1_ST,		-- Precharge All command
	PRECHARGE1_WAIT_ST,	-- Wait
	AUTOREF0_ST,		-- AUTOREF command
	AUTOREF0_WAIT_ST,	-- Wait
	AUTOREF1_ST,		-- AUTOREF command
	AUTOREF1_WAIT_ST,	-- Wait
	LMR2_ST,			-- Load mode register commnad (Base Mode Register setting)
	LMR2_WAIT_ST,		-- wait tMRD
	CMDRDY_ST
	);

	constant cnt200us		: unsigned(15 downto 0) := X"9C40";	-- FOR BOARD
--	constant cnt200us		: unsigned(15 downto 0) := X"0140";	-- FOR SIMULATION ONLY
	constant cnt200clk		: unsigned(15 downto 0) := X"00C8";
	constant cntNext		: unsigned( 3 downto 0) := "1111";

	signal counter16	: unsigned(15 downto 0);
	signal counter4		: unsigned( 3 downto 0);

	signal sync_rst_p	: std_logic_vector(2 downto 0);
	signal sync_rst		: std_logic;
	signal state_c		: DDR1_TYPE;
	signal state_n		: DDR1_TYPE;

	signal command	: std_logic_vector(3 downto 0);	-- CS_n & RAS_n & CAS_n & WE_n
	-- commands used in init phase
	constant DESEL_CMD		: std_logic_vector(3 downto 0) := "1111";
	constant NOP_CMD		: std_logic_vector(3 downto 0) := "0111";
	constant PRECHARGE_CMD	: std_logic_vector(3 downto 0) := "0010";
	constant AUTOREF_CMD	: std_logic_vector(3 downto 0) := "0001";
	constant LMR_CMD		: std_logic_vector(3 downto 0) := "0000";

	constant EXTD_LMR		: std_logic_vector(1 downto 0) := "01";
	constant BASE_LMR		: std_logic_vector(1 downto 0) := "00";

begin

	P_SYNCRST : process(rst, clk0)
	begin
	if rst = '1' then
		sync_rst_p <= (others => '1');
	elsif clk0'event and clk0='1' then
		sync_rst_p <= sync_rst_p(1 downto 0) & '0';
	end if;
	end process;

	sync_rst <= sync_rst_p(2);

	-------------------------------------------------------
	--	DDR1 memory controller initialization state machine
	-------------------------------------------------------
	P_SM_NEXT : process(clk0)
	begin
	if clk0'event and clk0='1' then
		if sync_rst = '1' then
			state_c <= INIT_ST;
		else
			state_c <= state_n;
		end if;
	end if;
	end process;

	P_SM : process(sync_rst, state_c, counter16, counter4)
	begin
	if sync_rst='1' then
		state_n <= INIT_ST;
	else
		case state_c is
		when INIT_ST =>
			state_n <= WAIT200US_ST;

		when WAIT200US_ST =>
			if counter16 = cnt200us then
				state_n <= CKEHIGH_ST;
			else
				state_n <= WAIT200US_ST;
			end if;

		when CKEHIGH_ST =>
			state_n <= CKEHIGH_WAIT_ST;

		when CKEHIGH_WAIT_ST =>
			if counter4 = cntNext then
				state_n <= PRECHARGE0_ST;
			else
				state_n <= CKEHIGH_WAIT_ST;
			end if;

		when PRECHARGE0_ST =>
			state_n <= PRECHARGE0_WAIT_ST;

		when PRECHARGE0_WAIT_ST =>
			if counter4 = cntNext then
				state_n <= LMR0_ST;
			else
				state_n <= PRECHARGE0_WAIT_ST;
			end if;

		when LMR0_ST =>
			state_n <= LMR0_WAIT_ST;

		when LMR0_WAIT_ST =>
			if counter4 = cntNext then
				state_n <= LMR1_ST;
			else
				state_n <= LMR0_WAIT_ST;
			end if;

		when LMR1_ST =>
			state_n <= LMR1_WAIT_ST;

		when LMR1_WAIT_ST =>
			if counter16 = cnt200clk then	-- wait for 200 clk cycles before any READ command
				state_n <= PRECHARGE1_ST;
			else
				state_n <= LMR1_WAIT_ST;
			end if;

		when PRECHARGE1_ST =>
			state_n <= PRECHARGE1_WAIT_ST;

		when PRECHARGE1_WAIT_ST =>
			if counter4 = cntNext then
				state_n <= AUTOREF0_ST;
			else
				state_n <= PRECHARGE1_WAIT_ST;
			end if;

		when AUTOREF0_ST =>
			state_n <= AUTOREF0_WAIT_ST;

		when AUTOREF0_WAIT_ST =>
			if counter4 = cntNext then
				state_n <= AUTOREF1_ST;
			else
				state_n <= AUTOREF0_WAIT_ST;
			end if;

		when AUTOREF1_ST =>
			state_n <= AUTOREF1_WAIT_ST;

		when AUTOREF1_WAIT_ST =>
			if counter4 = cntNext then
				state_n <= LMR2_ST;
			else
				state_n <= AUTOREF1_WAIT_ST;
			end if;

		when LMR2_ST =>
			state_n <= LMR2_WAIT_ST;

		when LMR2_WAIT_ST =>
			if counter4 = cntNext then
				state_n <= CMDRDY_ST;
			else
				state_n <= LMR2_WAIT_ST;
			end if;

		when CMDRDY_ST =>
			state_n <= CMDRDY_ST;

		when others =>
			state_n <= INIT_ST;

		end case;
	end if;
	end process;

	-- Set CKE high 200us after power-up
	P_CKE : process( clk0 )
	begin
	if clk0'event and clk0='1' then
		if rst='1' then
			cke_o	<= '0';

		else
			case state_c is
			when INIT_ST | WAIT200US_ST =>
				cke_o	<= '0';
			when others =>
				cke_o	<= '1';
			end case;
		end if;

	end if;
	end process;

	-- initialization commands
	P_CMD : process( clk0 )
	begin
	if clk0'event and clk0='1' then
		if rst='1' then
			command <= DESEL_CMD;
			addr_o	<= (others => '0');
			bank_o	<= (others => '0');

		else
			case state_c is
	-- 		when INIT_ST
	-- 			| WAIT200US_ST
	-- 			| CKEHIGH_ST
	-- 			| CKEHIGH_WAIT_ST
	-- 			| PRECHARGE0_WAIT_ST
	-- 			| LMR0_WAIT_ST
	-- 			| LMR1_WAIT_ST
	-- 			| PRECHARGE1_WAIT_ST
	-- 			| AUTOREF0_WAIT_ST
	-- 			| AUTOREF1_WAIT_ST
	-- 			| WAIT200CLK_ST
	-- 			| CMDRDY_ST =>
	--
	-- 			-- NOP
	-- 			command <= DESEL_CMD;
	-- 			addr_o	<= (others => '0');
	-- 			bank_o	<= (others => '0');

			when PRECHARGE0_ST | PRECHARGE1_ST =>
				command <= PRECHARGE_CMD;
				addr_o(9 downto 0)	<= (others => '0');
				addr_o(10) <= '1';
				addr_o(row_address - 1 downto 11) <= (others => '0');
				bank_o	<= (others => '0');

			when LMR0_ST =>
				command <= LMR_CMD;
				addr_o	<= ext_load_mode_register;
				bank_o	<= EXTD_LMR;

			when LMR1_ST =>
				command <= LMR_CMD;
				addr_o	<= load_mode_register_dllrst;
				bank_o	<= BASE_LMR;

			when AUTOREF0_ST | AUTOREF1_ST=>
				command <= AUTOREF_CMD;
				addr_o	<= (others => '0');
				bank_o	<= (others => '0');

			when LMR2_ST =>
				command <= LMR_CMD;
				addr_o	<= load_mode_register;
				bank_o	<= BASE_LMR;

			when others =>
				-- NOP
				command <= DESEL_CMD;
				addr_o	<= (others => '0');
				bank_o	<= (others => '0');

			end case;
		end if;
	end if;
	end process;

	cs_n_o	<= command(3);
	ras_n_o	<= command(2);
	cas_n_o	<= command(1);
	we_n_o	<= command(0);

	-- 4-bit wait counter
	P_CNT4 : process( clk0 )
	begin
	if clk0'event and clk0='1' then
		if rst='1' then
			counter4 <= (others => '0');
		else
			case state_c is
			when CKEHIGH_WAIT_ST
				| PRECHARGE0_WAIT_ST
				| LMR0_WAIT_ST
				| LMR2_WAIT_ST
				| PRECHARGE1_WAIT_ST
				| AUTOREF0_WAIT_ST
				| AUTOREF1_WAIT_ST =>

				counter4 <= counter4 + 1;

			when others =>
				counter4 <= (others => '0');

			end case;
		end if;
	end if;
	end process;

	-- 16-bit wait counter
	P_CNT16 : process( clk0 )
	begin
	if clk0'event and clk0='1' then
		if rst='1' then
			counter16 <= (others => '0');

		else
			case state_c is
			when WAIT200US_ST | LMR1_WAIT_ST =>
				counter16 <= counter16 + 1;
			when others =>
				counter16 <= (others => '0');
			end case;
		end if;
	end if;
	end process;

	-- After initializatio done, set init_done to high
	P_INIT_DONE : process( clk0 )
	begin
	if clk0'event and clk0='1' then
		if rst='1' then
			init_done <= '0';

		else
			if state_c = CMDRDY_ST	then
				init_done <= '1';
			else
				init_done <= '0';
			end if;
		end if;
	end if;
	end process;

end rtl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -