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

📄 hwtb_ddr1_top.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: hwtb_ddr1_top.vhd
--  /   /        Date Last Modified: 5/10/06
-- /___/   /\    Date Created:
-- \   \  /  \
--  \___\/\___\
-- 
--Device: Virtex-5
--Purpose: Top level design file. Instantiates DDR1 SDRAM controller and
--         clock generation logic. Also contains: (1) instantiation of a few
--         input buffers, (2) reset synchronization logic, (3) hardware
--         synthesizable test-bench that writes generates PRBS (pseudo-random
--         bit sequence) output to memory and compares readback data from
--         memory to verify correctness.
--Reference:
--    XAPP851
--Revision History:
--    Rev 0.1 - Created. Author: Toshihiko Moriyama. 1/23/06.
--    Rev 1.0 - Internal release. Author: Toshihiko Moriyama. 4/29/06.
--    Rev 1.1 - External release. Added header. Added app_WrData_AF to process
--              P_SM_MAIN. Added RST90 support. Removed unused signal
--              command(2:0). Added logic to prevent wait_counter wraparound.
--              Parameterized # clk outputs. 5/11/06.
-------------------------------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_misc.all;

library unisim ;
use unisim.vcomponents.all ;

library work;
use work.ddr1_parameters.all;
use work.pkg_prbs.all;

entity hwtb_ddr1_top is
port (
	rst_n			: in	std_logic;
	clk_in_p		: in	std_logic;
	clk_in_n		: in	std_logic;
	clk200_in_p		: in	std_logic;
	clk200_in_n		: in	std_logic;

	CKE			: out	std_logic;
	CK_p			: out	std_logic_vector(clk_width-1 downto 0);
	CK_n			: out	std_logic_vector(clk_width-1 downto 0);
	AD			: out	std_logic_vector(row_address - 1 downto 0);
	BA			: out	std_logic_vector(bank_address - 1 downto 0);
	CS_n			: out	std_logic_vector(no_of_cs - 1 downto 0);
	RAS_n			: out	std_logic;
	CAS_n			: out	std_logic;
	WE_n			: out	std_logic;
	DM			: out	std_logic_vector(dm_per_comp * no_of_comps - 1 downto 0);
	DQ			: inout	std_logic_vector(dq_per_comp * no_of_comps - 1 downto 0);
	DQS			: inout	std_logic_vector(dqs_per_comp * no_of_comps - 1 downto 0);

	phy_error		: out	std_logic;
	error			: out	std_logic;
	dcm_locked		: out	std_logic;
	ctrl_ready		: out	std_logic
);
end hwtb_ddr1_top;

-----------------------------------------------
architecture rtl of hwtb_ddr1_top is

	component ddr1_top is
	port (
	rst				: in	std_logic;
	rst90           : in    std_logic;
	clk0			: in	std_logic;
	clk90			: in	std_logic;

	-- IO signals
	CKE				: out	std_logic;
	CK				: out	std_logic_vector(clk_width-1 downto 0);
	AD				: out	std_logic_vector(row_address - 1 downto 0);
	BA				: out	std_logic_vector(bank_address - 1 downto 0);
	CS_n			: out	std_logic_vector(no_of_cs - 1 downto 0);
	RAS_n			: out	std_logic;
	CAS_n			: out	std_logic;
	WE_n			: out	std_logic;
	DM				: out	std_logic_vector(dm_per_comp * no_of_comps - 1 downto 0);
	DQ				: inout	std_logic_vector(dq_per_comp * no_of_comps - 1 downto 0);
	DQS				: inout	std_logic_vector(dqs_per_comp * no_of_comps - 1 downto 0);

	-- UI
	app_Addr		: in	std_logic_vector(35 downto 0);
	app_AddrEn		: in	std_logic;
	app_WrData		: in	std_logic_vector(data_width*2 - 1 downto 0);
	app_DataMask	: in	std_logic_vector(data_mask_width*2 - 1 downto 0);
	app_DataEn		: in	std_logic;
	app_rd_data		: out	std_logic_vector(data_width*2 - 1 downto 0);
	app_rd_valid	: out	std_logic;
	app_addr_AF		: out	std_logic;	-- Address FIFIO almost full
	app_WrData_AF	: out	std_logic;	-- Write data FIFO almost full

	ctrl_rdy		: out	std_logic;
	phy_error		: out	std_logic
	);
	end component;

	component CLK_module is
	Port (
	rst				: in std_logic;
	clk200_in		: in std_logic;
	clk_in			: in std_logic;

	clk0			: out std_logic;
	clk90			: out std_logic;
	locked			: out std_logic
	);
	end component;

	TYPE DDR1_TYPE is (
	CNTINIT_ST,		-- wait 200us
	WRITE_ST,
	WRITE_WAIT_ST,
	READ_ST,
	READ_WAIT_ST
	);

	signal state_c		: DDR1_TYPE;
	signal state_n		: DDR1_TYPE;

	signal rst				: std_logic;
	signal rst_p			: std_logic_vector(3 downto 0);
	signal rst_i			: std_logic;
        signal rst90_p                  : std_logic_vector(3 downto 0);
        signal rst90_i                  : std_logic;
	signal dcm_locked_i		: std_logic;
	signal clk0				: std_logic;
	signal clk90			: std_logic;
	signal clk_in			: std_logic;
	signal clk200_in		: std_logic;
	signal CK			: std_logic_vector(clk_width-1 downto 0);

	signal app_Addr			: std_logic_vector(35 downto 0);
	signal app_AddrEn		: std_logic;
	signal app_WrData		: std_logic_vector(data_width*2 - 1 downto 0);
	signal app_DataMask		: std_logic_vector(data_mask_width*2 - 1 downto 0);
	signal app_DataEn		: std_logic;
	signal app_rd_data		: std_logic_vector(data_width*2 - 1 downto 0);
	signal app_rd_valid		: std_logic;
	signal app_addr_AF		: std_logic;	-- Address FIFIO almost full
	signal app_WrData_AF	: std_logic;	-- Write data FIFO almost full
	signal ctrl_rdy			: std_logic;

	signal addr_row			: std_logic_vector(row_address - 1 downto 0);
	signal addr_col			: std_logic_vector(9 downto 0);
	signal bank				: std_logic_vector(bank_address - 1 downto 0);
	signal rd_data			: std_logic_vector(data_width*2 - 1 downto 0);
	signal app_rd_valid_p	: std_logic;
	signal rd_data_exp		: std_logic_vector(data_width*2 - 1 downto 0);
	signal error_i			: std_logic;

	signal wait_counter		: std_logic_vector(3 downto 0);

	-- commands used in init phase
	constant CMD_LMR		: std_logic_vector(2 downto 0) := "000";
	constant CMD_REF		: std_logic_vector(2 downto 0) := "001";
	constant CMD_PRE		: std_logic_vector(2 downto 0) := "010";
	constant CMD_ACT		: std_logic_vector(2 downto 0) := "011";
	constant CMD_WR			: std_logic_vector(2 downto 0) := "100";
	constant CMD_RD			: std_logic_vector(2 downto 0) := "101";

begin

	rst <= not rst_n;

	-- Application clock
	IBUFGDS_CLK : IBUFGDS
	generic map (
	IOSTANDARD => "LVDS_25")
	port map ( O => clk_in, I => clk_in_p, IB => clk_in_n );

	-- IDELAYCTRL clock
	IBUFGDS_CLK200 : IBUFGDS
	generic map (
	IOSTANDARD => "LVPECL_25")
	port map ( O => clk200_in, I => clk200_in_p, IB => clk200_in_n );

        -- Differential clock outputs pairs
        G_OBUFDS_CK: for I in 0 to clk_width-1 generate                
                OBUFDS_CK : OBUFDS
                port map ( O => CK_p(I), OB => CK_n(I), I => CK(I));
        end generate;

	-- DCM locked status output to LED
	dcm_locked <= dcm_locked_i;

	P_RST : process(rst, dcm_locked_i, clk0)
	begin
	if rst='1' or dcm_locked_i='0' then
		rst_p <=  (others => '1');
	elsif clk0'event and clk0 = '1' then
		rst_p <= rst_p(2 downto 0) & '0';
	end if;
	end process;

	rst_i <= rst_p(3);

        -- Use RST input or DCM locked status to asynchronously
        -- assert reset, and deassert reset synchronously (could
        -- share flops with clk0 reset circuit to reduce another
        -- potential metastable path, and to better ensure rst
        -- and rst90 deasserted with 1/4 cycle of each other, but
        -- it's not a big deal - okay even if we're off by a clock
        -- cycle).
        P_RST90 : process(rst, dcm_locked_i, clk90)
        begin
	if rst='1' or dcm_locked_i='0' then
		rst90_p <=  (others => '1');
	elsif clk90'event and clk90 = '1' then
		rst90_p <= rst90_p(2 downto 0) & '0';
	end if;          
        end process;

	rst90_i <= rst90_p(3);
        
	P_SM_NEXT : process(clk0)
	begin
	if clk0'event and clk0='1' then
		if rst_i = '1' then
			state_c <= CNTINIT_ST;
		else
			state_c <= state_n;
		end if;
	end if;
	end process;

	-- Main state machine
	P_SM_MAIN : process(rst_i, state_c, ctrl_rdy, wait_counter, app_addr_AF, app_WrData_AF)
	begin
	if rst_i = '1' then
		state_n <= CNTINIT_ST;
	else
		case state_c is
		-- Wait until initialization is done
		when CNTINIT_ST =>
			if ctrl_rdy = '1' then
				state_n <= WRITE_ST;
			else
				state_n <= CNTINIT_ST;
			end if;

		when WRITE_ST =>
			state_n <= WRITE_WAIT_ST;

		when WRITE_WAIT_ST =>
			if (wait_counter >= 5) and (app_addr_AF = '0') and (app_WrData_AF = '0') then
				state_n <= READ_ST;
			else
				state_n <= WRITE_WAIT_ST;
			end if;

		when READ_ST =>
			state_n <= READ_WAIT_ST;

		when READ_WAIT_ST =>
			if (wait_counter >= 5) and (app_addr_AF = '0') and (app_WrData_AF = '0') then
				state_n <= WRITE_ST;
			else
				state_n <= READ_WAIT_ST;
			end if;

		end case;
	end if;
	end process;

	-- counter
	P_COUNTER : process(clk0)
	begin
	if clk0'event and clk0='1' then
		if rst_i = '1' then
			wait_counter <= (others => '0');
		else
			case state_c is
			when WRITE_WAIT_ST | READ_WAIT_ST =>
                                -- prevent wraparound in case takes longer
                                -- than 16 counts for write FIFO to empty
                                if wait_counter /= "1111" then 
                                        wait_counter <= wait_counter + 1;
                                end if;

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

			end case;

		end if;
	end if;
	end process;

	-- address
	P_ADR : process(clk0)
	begin
	if clk0'event and clk0='1' then
		if rst_i = '1' then
			addr_row <= (others => '0');
			addr_col <= (others => '0');
			bank <= (others => '0');
		else
			if state_c = READ_ST then
				addr_col <= addr_col + 4;

		 		if addr_col(4 downto 2) = "111" then
		 			addr_row <= addr_row + 1;
		 		else
		 			addr_row <= addr_row;
		 		end if;

		 		if addr_col(5 downto 2) = "1111" then
					bank <= bank + 1;
				else
					bank <= bank;
				end if;

			else
				addr_col <= addr_col;
	 			addr_row <= addr_row;
				bank <= bank;
			end if;
		end if;
	end if;
	end process;

	-- command
	P_COMMAND : process(clk0)
	begin
	if clk0'event and clk0='1' then
		if rst_i='1' then
			app_Addr <= (others => '0');
			app_AddrEn <= '0';

		else
			case state_c is
			when CNTINIT_ST =>
				app_Addr <= (others => '0');
				app_AddrEn <= '0';

			when WRITE_ST =>
				app_Addr(9 downto 0) <= addr_col;
				app_Addr(10) <= '0';
				app_Addr(23 downto 11) <= addr_row;
				app_Addr(25 downto 24) <= bank;
				app_Addr(31 downto 26) <= (others => '0');
				app_Addr(34 downto 32) <= CMD_WR;
				app_Addr(35) <= '0';
				app_AddrEn <= '1';

			when WRITE_WAIT_ST =>
				app_Addr <= (others => '0');
				app_AddrEn <= '0';

			when READ_ST =>
				app_Addr(9 downto 0) <= addr_col;
				app_Addr(10) <= '0';
				app_Addr(23 downto 11) <= addr_row;
				app_Addr(25 downto 24) <= bank;
				app_Addr(31 downto 26) <= (others => '0');
				app_Addr(34 downto 32) <= CMD_RD;
				app_Addr(35) <= '0';
				app_AddrEn <= '1';

			when READ_WAIT_ST =>
				app_Addr <= (others => '0');
				app_AddrEn <= '0';

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


	P_WRITE_DATA : process(clk0)
	begin
	if clk0'event and clk0='1' then
		if rst_i = '1' then
			app_WrData(15 downto 0) <= X"1234";
			app_WrData(data_width*2 - 1 downto 16) <= (others => '0');
			app_DataEn <= '0';

		else
			if (state_c = WRITE_ST) or ((state_c = WRITE_WAIT_ST) and (wait_counter=0)) then
				app_WrData <= PRBS(app_WrData);
				app_DataEn <= '1';
			else
				app_WrData <= app_WrData;
				app_DataEn <= '0';
			end if;

		end if;
	end if;
	end process;

	app_DataMask <= (others => '0');

	P_READ_DATA : process(clk0)
	begin
	if clk0'event and clk0='1' then
		if rst_i = '1' then
			rd_data <= (others => '0');
			app_rd_valid_p <= '0';
			rd_data_exp <= PRBS(app_WrData);
			error_i <= '0';

		else
			if app_rd_valid = '1' then
				rd_data <= app_rd_data;
			else
				rd_data <= rd_data;
			end if;

			app_rd_valid_p <= app_rd_valid;

			if app_rd_valid_p = '1' then
				if rd_data_exp = rd_data then
					error_i <= '0';
				else
					error_i <= '1';
				end if;
				rd_data_exp <= PRBS(rd_data);
			else
				error_i <= error_i;
				rd_data_exp <= rd_data_exp;
			end if;

		end if;
	end if;
	end process;

	error <= error_i;


	-- MODULEs
	----------------------------------------------------------------

	CLK_MODULE_I : CLK_module
	port map (
	rst				=> rst,
	clk200_in		=> clk200_in,
	clk_in			=> clk_in,

	clk0			=> clk0,
	clk90			=> clk90,
	locked			=> dcm_locked_i
	);


	DDR1_TOP_I : ddr1_top
	port map (
	rst				=> rst_i,
        rst90                   => rst90_i, 
	clk0			=> clk0,
	clk90			=> clk90,

	-- IO signals
	CKE				=> CKE,
	CK				=> CK,
	AD				=> AD,
	BA				=> BA,
	CS_n			=> CS_n,
	RAS_n			=> RAS_n,
	CAS_n			=> CAS_n,
	WE_n			=> WE_n,
	DM				=> DM,
	DQ				=> DQ,
	DQS				=> DQS,

	-- UI
	app_Addr		=> app_Addr,
	app_AddrEn		=> app_AddrEn,
	app_WrData		=> app_WrData,
	app_DataMask	=> app_DataMask,
	app_DataEn		=> app_DataEn,
	app_rd_data		=> app_rd_data,
	app_rd_valid	=> app_rd_valid,
	app_addr_AF		=> app_addr_AF,
	app_WrData_AF	=> app_WrData_AF,

	ctrl_rdy		=> ctrl_rdy,
	phy_error		=> phy_error
	);

	ctrl_ready <= ctrl_rdy;

end rtl;

⌨️ 快捷键说明

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