📄 sdram.vhd
字号:
-------------------------------------------------------------------
-- 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 + -