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

📄 command.vhd

📁 SDRAM基础性控制核 很有用的 VHDL状态机实现
💻 VHD
📖 第 1 页 / 共 2 页
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;



entity command is
	
	generic (
         ASIZE          : integer := 22;
         DSIZE          : integer := 32;
         ROWSIZE        : integer := 12;
         COLSIZE        : integer := 8;
         BANKSIZE       : integer := 2;
         ROWSTART       : integer := 8;         
         COLSTART       : integer := 0;
         BANKSTART      : integer := 20 	-- Starting position of the bank address within ADDR
	);

	port (
		CLK			: in	std_logic;	-- System Clock
		RESET_N		: in	std_logic;		   -- System Reset
		SADDR		: in	std_logic_vector(ASIZE-1 downto 0);	-- Address
		NOP			: in	std_logic;	-- Decoded NOP command
		READA		: in	std_logic;		-- Decoded READA command
		WRITEA		: in	std_logic;		-- Decoded WRITEA command
		REFRESH		: in	std_logic;		-- Decoded REFRESH command
		PRECHARGE	: in	std_logic;		-- Decoded PRECHARGE command
		LOAD_MODE	: in	std_logic;		-- Decoded LOAD_MODE command
		SC_CL		: in	std_logic_vector(1 downto 0);		-- Programmed CAS latency
		SC_RC		: in	std_logic_vector(1 downto 0);		-- Programmed RC delay
		SC_RRD		: in	std_logic_vector(3 downto 0);		-- Programmed RRD delay
		SC_PM		: in	std_logic;				-- programmed Page Mode
		SC_BL		: in	std_logic_vector(3 downto 0);		-- Programmed burst length
		REF_REQ		: in	std_logic;				-- Hidden refresh request
		REF_ACK		: out	std_logic;				-- Refresh request acknowledge
		CM_ACK		: out	std_logic;				-- Command acknowledge
		OE			: out	std_logic;			-- OE signal for data path module
		SA			: out	std_logic_vector(11 downto 0);		-- SDRAM address
		BA			: out	std_logic_vector(1 downto 0);		-- SDRAM bank address
		--CKE			: out	std_logic;				-- SDRAM clock enable
		RAS_N		: buffer 	std_logic;				-- SDRAM RAS
		CAS_N		: buffer	std_logic;				-- SDRAM CAS
		WE_N		: buffer	std_logic;				-- SDRAM WE_N
        --------------------------------------changed------------------
        DATAVALID   : out   std_logic
	);
end command;

architecture RTL of command is

	-- signal declarations
	--signal	do_nop 			: std_logic;
	signal	do_reada 		: std_logic;
    signal	do_writea 		: std_logic;
    signal	do_writea1 		: std_logic;
    signal	do_refresh 		: std_logic;
    signal	do_precharge 	: std_logic;
    signal	do_load_mode 	: std_logic;
    signal	command_done 	: std_logic;
    signal	command_delay 	: std_logic_vector(7 downto 0);
    signal	rw_shift 		: std_logic_vector(3 downto 0);
    signal	do_act 			: std_logic;			                       
    signal	rw_flag_R1 		: std_logic;			                       
    signal	do_rw 			: std_logic;			                       
    signal	oe_shift 		: std_logic_vector(7 downto 0);
    signal	oe1 			: std_logic;				                       
    signal	oe2 			: std_logic;				                       
    signal	oe3 			: std_logic;				                       
    signal	oe4 			: std_logic;				                       
    signal	rp_shift 		: std_logic_vector(3 downto 0);
    signal	rp_done			: std_logic;
	signal	rowaddr 		: std_logic_vector(ROWSIZE-1 downto 0);
	signal	coladdr 		: std_logic_vector(COLSIZE-1 downto 0);
	signal	bankaddr 		: std_logic_vector(BANKSIZE-1 downto 0);
    signal  datavalid_delay : std_logic_vector(5 downto 0);
    signal  datavalid_end   : std_logic;
    signal  datavalid1   : std_logic;
    signal  datavalid2   : std_logic;
	signal	REF_REQ_int		: std_logic;
	

begin

	rowaddr   <= SADDR(ROWSTART + ROWSIZE - 1 downto ROWSTART);      -- assignment of the row address bits from SADDR
	coladdr   <= SADDR(COLSTART + COLSIZE - 1 downto COLSTART);      -- assignment of the column address bits
	bankaddr  <= SADDR(BANKSTART + BANKSIZE - 1 downto BANKSTART);   -- assignment of the bank address bits



	-- This process monitors the individual command lines and issues a command
	-- to the next stage if there currently another command already running.
	--
	process(CLK, RESET_N)
	begin
		if (RESET_N = '0') then
			--do_nop          <= '0';
			do_reada        <= '0';
			do_writea       <= '0';
			do_refresh      <= '0';
			do_precharge    <= '0';
			do_load_mode    <= '0';
			command_done    <= '0';
			command_delay   <= (others => '0');
			rw_flag_R1         <= '0';
			rp_shift        <= (others => '0');
			rp_done         <= '0';
            do_writea1      <= '0';
		elsif rising_edge(CLK) then --  Issue the appropriate command if the sdram is not currently busy     
                if ((REF_REQ = '1' or REFRESH = '1') and command_done = '0' and do_refresh = '0' and rp_done = '0'         -- Refresh
                        and do_reada = '0' and do_writea = '0') then
                        do_refresh <= '1';                                   
                else
                        do_refresh <= '0';
                end if;
                       

                if ((READA = '1') and (command_done = '0') and (do_reada = '0') and (rp_done = '0') and (REF_REQ = '0')) then   -- READA
                        do_reada <= '1';
                else
                        do_reada <= '0';
                end if;
                    
                if ((WRITEA = '1') and (command_done = '0') and (do_writea = '0') and (rp_done = '0') and (REF_REQ = '0')) then -- WRITEA
                        do_writea <= '1';
                        do_writea1 <= '1';
                else
                        do_writea <= '0';
                        do_writea1 <= '0';
                end if;

                if ((PRECHARGE = '1') and (command_done = '0') and (do_precharge = '0')) then      
                		do_precharge <= '1';
				else
                        do_precharge <= '0';
                end if;
 
                if ((LOAD_MODE = '1') and (command_done = '0') and (do_load_mode = '0')) then                           -- LOADMODE
                        do_load_mode <= '1';
                else
                        do_load_mode <= '0';
                end if;
                                               
	-- set command_delay shift register and command_done flag
	-- The command delay shift register is a timer that is used to ensure that
	-- the SDRAM devices have had sufficient time to finish the last command.

                if ((do_refresh = '1') or (do_reada = '1') or (do_writea = '1') or (do_precharge = '1') or (do_load_mode = '1')) then
                        command_delay 	<= "11111111";
                        command_done  	<= '1';
                        rw_flag_R1		<= do_reada;                                                  

                else
                        command_done        		<= command_delay(0);                -- the command_delay shift operation
                        command_delay(6 downto 0)  	<= command_delay(7 downto 1);                                
                        command_delay(7)    		<= '0';
                end if;
                
 
	 -- start additional timer that is used for the refresh, writea, reada commands               
                if (command_delay(0) = '0' and command_done = '1') then
                        rp_shift <= "1111";
                        rp_done  <= '1';
                else
                        rp_done         		<= rp_shift(0);
                        rp_shift(2 downto 0)   	<= rp_shift(3 downto 1);
                        rp_shift(3)     		<= '0';
                end if;
		end if;
	end process;




	-- logic that generates the OE signal for the data path module
	-- For normal burst write the duration of OE is dependent on the configured burst length.
	-- For page mode accesses(SC_PM=1) the OE signal is turned on at the start of the write command
	-- and is left on until a PRECHARGE(page burst terminate) is detected.
	--
	process(CLK, RESET_N)
	begin
		if (RESET_N = '0') then
                oe_shift <= (others => '0');
                oe1      <= '0';
                oe2      <= '0';
                oe3      <= '0';
                oe4      <= '0';
                OE       <= '0';
		elsif rising_edge(CLK) then
                if (SC_PM = '0') then   ----
                        if (do_writea1 = '1') then
                                if (SC_BL = "0001") then                       --  Set the shift register to the appropriate
                                        oe_shift <= (others => '0');                -- value based on burst length.
                                elsif (SC_BL = "0010") then
                                        oe_shift <= "00000001";
                                elsif (SC_BL = "0100") then
                                        oe_shift <= "00000111";

⌨️ 快捷键说明

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