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

📄 sdram.vhd

📁 vhdl 编写的sdram controler, 双通道
💻 VHD
📖 第 1 页 / 共 2 页
字号:

-------------------------------------------------------------------
-- By Fangang
-- 2003/05/30
-- SDRAM controller for C6send
-------------------------------------------------------------------

-- 1>有两个写通道, (full,cmd,rdcmden), (rddataen,datain,order)
-- 2>有两个读通道, (full,cmd,rdcmden), (datav,dataout,order)
-- 3>rrst为'0'后的128us为SDRAM初始化时间,系统不会处理读写命令
-- 4>sdram接口: cs,ras,cas,we,addr,data
-- 5>内部自含 refresh 和 init 功能

---------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use	ieee.std_logic_unsigned.all;

entity sdram is
generic ( DATAWIDTH		:integer:=16;
		  SYSCLK_FREQ	:std_logic_vector(6 downto 0):="1100100");
port(
		sysclk			:in std_logic;
		rrst			:in std_logic;

		--sdram的外部接口
		sdram_cs		:out std_logic;
		sdram_ras		:out std_logic;
		sdram_cas		:out std_logic;
		sdram_we		:out std_logic;
		sdram_addr		:out std_logic_vector(11 downto 0);
		sdram_data		:inout std_logic_vector(DATAWIDTH-1 downto 0);
--		sdram_data		:out std_logic_vector(DATAWIDTH-1 downto 0);
--		sdram_datain	:in std_logic_vector(DATAWIDTH-1 downto 0);

		--写通道1
		--w_datain可在w_rddataen有效后的第三个CLK上沿锁存
		--wcmd从高位至低位分别为order4,page12,addr8,num8
		Iw_cmdfull		:in std_logic;
		Iw_cmd			:in std_logic_vector(32 downto 0);
		Iw_rdcmden		:out std_logic;
		Iw_rddataen		:out std_logic;
		Iw_datain		:in std_logic_vector(DATAWIDTH-1 downto 0);

		--写通道2
		IIw_cmdfull		:in std_logic;
		IIw_cmd			:in std_logic_vector(32 downto 0);
		IIw_rdcmden		:out std_logic;
		IIw_rddataen	:out std_logic;
		IIw_datain		:in std_logic_vector(DATAWIDTH-1 downto 0);

		--读通道1
		--读 不支持num=1
		Ir_cmdfull		:in std_logic;
		Ir_cmd			:in std_logic_vector(32 downto 0);
		Ir_rdcmden		:out std_logic;
		Ir_datav		:out std_logic;


		--读通道2
		IIr_cmdfull		:in std_logic;
		IIr_cmd			:in std_logic_vector(32 downto 0);
		IIr_rdcmden		:out std_logic;
		IIr_datav		:out std_logic;

		r_dataout		:out std_logic_vector(DATAWIDTH-1 downto 0);
		
		--读SDRAM时,order在datav的开始有效, 写SDRAM时,order在rddataen整个区间有效
		order			:out std_logic_vector(4 downto 0)
	);
end sdram;

--------------------------------------------------------------------

architecture a of sdram is 

constant INITTIME			:std_logic_vector(7 downto 0) := "10000000";
--constant INITTIME			:std_logic_vector(7 downto 0) := "00000100";

signal cntL_sys				:std_logic_vector(6 downto 0);
signal oneus				:std_logic;
signal cnt_oneus			:std_logic_vector(7 downto 0);
signal init_end				:std_logic;

signal need_init0			:std_logic;
signal need_init1			:std_logic;
signal clr_need_init0		:std_logic;
signal clr_need_init1		:std_logic;

signal need_refresh			:std_logic;
signal clr_need_refresh		:std_logic;
signal ref_cnt				:std_logic_vector(11 downto 0);
signal ref_cnt_end			:std_logic_vector(11 downto 0);

signal Pcmdfull				:std_logic;
signal clr_Pcmdfull			:std_logic;
signal Pcmdtype				:std_logic_vector(1 downto 0);		--00 null 01 read 10 write 11 others
signal Pwhich_channel		:std_logic;
signal Pcmd					:std_logic_vector(32 downto 0);
signal Pcmd_ACT_TIME		:std_logic_vector(7 downto 0);
signal Pcmd_WRITE_TIME		:std_logic_vector(7 downto 0);
signal Pcmd_READ_TIME		:std_logic_vector(7 downto 0);
signal Pcmd_BST_TIME		:std_logic_vector(7 downto 0);
signal Pcmd_PRE_TIME		:std_logic_vector(7 downto 0);
signal Pcmd_REF_TIME		:std_logic_vector(7 downto 0);
signal Pcmd_MRS_TIME		:std_logic_vector(7 downto 0);
signal Pcmd_END_TIME		:std_logic_vector(7 downto 0);

signal sbusy				:std_logic;
signal clr_sbusy			:std_logic;
signal Scmdtype				:std_logic_vector(1 downto 0);		--00 null 01 read 10 write 11 others
signal Swhich_channel		:std_logic;
signal Scmd					:std_logic_vector(32 downto 0);
signal Scmd_ACT_TIME		:std_logic_vector(7 downto 0);
signal Scmd_WRITE_TIME		:std_logic_vector(7 downto 0);
signal Scmd_READ_TIME		:std_logic_vector(7 downto 0);
signal Scmd_BST_TIME		:std_logic_vector(7 downto 0);
signal Scmd_PRE_TIME		:std_logic_vector(7 downto 0);
signal Scmd_REF_TIME		:std_logic_vector(7 downto 0);
signal Scmd_MRS_TIME		:std_logic_vector(7 downto 0);
signal Scmd_END_TIME		:std_logic_vector(7 downto 0);

signal s_cnt				:std_logic_vector(7 downto 0);
signal do_act				:std_logic;
signal do_write				:std_logic;
signal do_read				:std_logic;
signal do_bst				:std_logic;
signal do_pre				:std_logic;
signal do_ref				:std_logic;
signal do_mrs				:std_logic;

signal sdram_cs_p			:std_logic;
signal sdram_ras_p			:std_logic;
signal sdram_cas_p			:std_logic;
signal sdram_we_p			:std_logic;
signal sdram_addr_p			:std_logic_vector(11 downto 0);

signal do_dataoe			:std_logic;
signal rddataen				:std_logic;
signal do_dataoe_d			:std_logic;
signal dataoe				:std_logic;
signal w_datain				:std_logic_vector(DATAWIDTH-1 downto 0);
signal sdram_dataout		:std_logic_vector(DATAWIDTH-1 downto 0);

signal datav_p				:std_logic;
signal qqr_ch				:std_logic;
signal qqr_ch4				:std_logic;
signal qqr_ch5				:std_logic;
signal datav_p1				:std_logic;
signal datav_p2				:std_logic;
signal datav_p3				:std_logic;
signal datav_p4				:std_logic;
signal datav_p5				:std_logic;

signal order_i				:std_logic_vector(4 downto 0);

begin

--产生 oneus 信号
process(sysclk) begin
	if rising_edge(sysclk) then
		if rrst='1' then
			cntL_sys <= (others=>'0');
		else
			cntL_sys <= cntL_sys+1;
		end if;

		oneus <= cntL_sys(6) and cntL_sys(5) and cntL_sys(4) and cntL_sys(3) and
				 cntL_sys(2) and cntL_sys(1) and cntL_sys(0);
	end if;
end process;

--产生 init_end 信号
process(sysclk) begin
	if rising_edge(sysclk) then
		if rrst='1' then
			cnt_oneus <= (others=>'0');
		elsif oneus='1' then
			if cnt_oneus>=INITTIME then
				cnt_oneus <= INITTIME;
			else
				cnt_oneus <= cnt_oneus+1;
			end if;
		else
			cnt_oneus <= cnt_oneus;
		end if;

		if cnt_oneus >= INITTIME then
			init_end <= '1';
		else
			init_end <= '0';
		end if;
	end if;
end process;

--产生 需初始化0 和 需初始化1 信号
process(sysclk) begin
	if rising_edge(sysclk) then
		if rrst='1' then
			need_init0 <= '0';
			need_init1 <= '0';
		else
			if cnt_oneus=INITTIME-1 and cntL_sys=5 then
				need_init0 <= '1';
			elsif clr_need_init0='1' then
				need_init0 <= '0';
			else
				need_init0 <= need_init0;
			end if;
			if cnt_oneus=INITTIME-1 and cntL_sys=35 then
				need_init1 <= '1';
			elsif clr_need_init1='1' then
				need_init1 <= '0';
			else
				need_init1 <= need_init1;
			end if;
		end if;
	end if;
end process;

--产生 need_refresh 信号
ref_cnt_end <= (SYSCLK_FREQ * "11111") - 1;
process(sysclk) begin
	if rising_edge(sysclk) then
		if rrst='1' then
			need_refresh <= '0';
			ref_cnt <= (others=>'0');
		else
			if ref_cnt=5 then
				need_refresh <= '1';
			elsif clr_need_refresh='1' then
				need_refresh <= '0';
			else
				need_refresh <= need_refresh;
			end if;
			
			if ref_cnt=ref_cnt_end then
				ref_cnt <= (others=>'0');
			else
				ref_cnt <= ref_cnt+1;
			end if;
		end if;	
	end if;
end process;

--根据 2init+ 1ref + 2write + 2read 生成内部的命令Pcmd
process(sysclk) begin
	if rising_edge(sysclk) then
		if rrst='1' then
			Pcmdfull		<= '0';
			Pcmdtype		<= "00";
			Pwhich_channel	<= '0';
			Pcmd			<= (others=>'0');
			Pcmd_ACT_TIME	<= (others=>'1');
			Pcmd_WRITE_TIME	<= (others=>'1');
			Pcmd_READ_TIME	<= (others=>'1');
			Pcmd_BST_TIME	<= (others=>'1');
			Pcmd_PRE_TIME	<= (others=>'1');
			Pcmd_REF_TIME	<= (others=>'1');
			Pcmd_MRS_TIME	<= (others=>'1');
			Pcmd_END_TIME	<= (others=>'1');
			Iw_rdcmden		<= '0';
			IIw_rdcmden		<= '0';
			Ir_rdcmden		<= '0';
			IIr_rdcmden		<= '0';
			clr_need_init0	<= '0';
			clr_need_init1	<= '0';
			clr_need_refresh<= '0';
		elsif Pcmdfull='1' then
			if clr_Pcmdfull='1' then
				Pcmdfull <= '0';
			else
				Pcmdfull <= Pcmdfull;
			end if;
			Pcmdtype		<= Pcmdtype;
			Pwhich_channel	<= Pwhich_channel;
			Pcmd			<= Pcmd;
			Pcmd_ACT_TIME	<= Pcmd_ACT_TIME;
			Pcmd_WRITE_TIME	<= Pcmd_WRITE_TIME;
			Pcmd_READ_TIME	<= Pcmd_READ_TIME;
			Pcmd_BST_TIME	<= Pcmd_BST_TIME;
			Pcmd_PRE_TIME	<= Pcmd_PRE_TIME;
			Pcmd_REF_TIME	<= Pcmd_REF_TIME;
			Pcmd_MRS_TIME	<= Pcmd_MRS_TIME;
			Pcmd_END_TIME	<= Pcmd_END_TIME;
			Iw_rdcmden		<= '0';
			IIw_rdcmden		<= '0';
			Ir_rdcmden		<= '0';
			IIr_rdcmden		<= '0';
			clr_need_init0	<= '0';
			clr_need_init1	<= '0';
			clr_need_refresh<= '0';
		elsif init_end='0' then
			if need_init0='1' then
				Pcmdfull		<= '1';
				Pcmdtype		<= "11";
				Pwhich_channel	<= '0';
				Pcmd			<= (others=>'0');
				Pcmd_ACT_TIME	<= (others=>'1');
				Pcmd_WRITE_TIME	<= (others=>'1');
				Pcmd_READ_TIME	<= (others=>'1');
				Pcmd_BST_TIME	<= (others=>'1');
				Pcmd_PRE_TIME	<= "00000000";		-- 0
				Pcmd_REF_TIME	<= "00000011";		-- 3
				Pcmd_MRS_TIME	<= (others=>'1');
				Pcmd_END_TIME	<= "00001100";		-- 12
				Iw_rdcmden		<= '0';
				IIw_rdcmden		<= '0';
				Ir_rdcmden		<= '0';
				IIr_rdcmden		<= '0';
				clr_need_init0	<= '1';
				clr_need_init1	<= '0';
				clr_need_refresh<= '0';
			elsif need_init1='1' then
				Pcmdfull		<= '1';
				Pcmdtype		<= "11";
				Pwhich_channel	<= '0';
				Pcmd			<= (others=>'0');
				Pcmd_ACT_TIME	<= (others=>'1');
				Pcmd_WRITE_TIME	<= (others=>'1');
				Pcmd_READ_TIME	<= (others=>'1');
				Pcmd_BST_TIME	<= (others=>'1');
				Pcmd_PRE_TIME	<= (others=>'1');
				Pcmd_REF_TIME	<= "00000000";		-- 0
				Pcmd_MRS_TIME	<= "00001001";		-- 9
				Pcmd_END_TIME	<= "00001100";		-- 12
				Iw_rdcmden		<= '0';
				IIw_rdcmden		<= '0';
				Ir_rdcmden		<= '0';
				IIr_rdcmden		<= '0';
				clr_need_init0	<= '0';
				clr_need_init1	<= '1';
				clr_need_refresh<= '0';
			else
				Pcmdfull		<= Pcmdfull;
				Pcmdtype		<= Pcmdtype;
				Pwhich_channel	<= Pwhich_channel;
				Pcmd			<= Pcmd;
				Pcmd_ACT_TIME	<= Pcmd_ACT_TIME;
				Pcmd_WRITE_TIME	<= Pcmd_WRITE_TIME;
				Pcmd_READ_TIME	<= Pcmd_READ_TIME;
				Pcmd_BST_TIME	<= Pcmd_BST_TIME;
				Pcmd_PRE_TIME	<= Pcmd_PRE_TIME;
				Pcmd_REF_TIME	<= Pcmd_REF_TIME;
				Pcmd_MRS_TIME	<= Pcmd_MRS_TIME;
				Pcmd_END_TIME	<= Pcmd_END_TIME;
				Iw_rdcmden		<= '0';
				IIw_rdcmden		<= '0';
				Ir_rdcmden		<= '0';
				IIr_rdcmden		<= '0';
				clr_need_init0	<= '0';
				clr_need_init1	<= '0';
				clr_need_refresh<= '0';
			end if;
		else
			if need_refresh='1' then
				Pcmdfull		<= '1';
				Pcmdtype		<= "11";
				Pwhich_channel	<= '0';
				Pcmd			<= (others=>'0');
				Pcmd_ACT_TIME	<= (others=>'1');
				Pcmd_WRITE_TIME	<= (others=>'1');
				Pcmd_READ_TIME	<= (others=>'1');
				Pcmd_BST_TIME	<= (others=>'1');
				Pcmd_PRE_TIME	<= (others=>'1');
				Pcmd_REF_TIME	<= "00000000";
				Pcmd_MRS_TIME	<= (others=>'1');
				Pcmd_END_TIME	<= "00000111";		-- 7
				Iw_rdcmden		<= '0';
				IIw_rdcmden		<= '0';
				Ir_rdcmden		<= '0';
				IIr_rdcmden		<= '0';
				clr_need_init0	<= '0';
				clr_need_init1	<= '0';
				clr_need_refresh<= '1';
			elsif Ir_cmdfull='1' then
				Pcmdfull		<= '1';
				Pcmdtype		<= "01";
				Pwhich_channel	<= '0';
				Pcmd			<= Ir_cmd;
				Pcmd_ACT_TIME	<= "00000000";		-- 0

⌨️ 快捷键说明

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