📄 fsm_sdram.vhd
字号:
sd_a <= (others=>'0');
when st_idle_2_ref_1 => -- Auto refresh command sd_cs_n <= '0'; sd_ras_n <= '0'; sd_cas_n <= '0'; sd_we_n <= '1'; sd_dqm <= "11"; sd_ba <= "00"; sd_a <= (others=>'0'); when st_idle_2_ref_2 => -- tRC time needed with nop command ( min 65ns ) sd_cs_n <= '1'; sd_ras_n <= '0'; sd_cas_n <= '0'; sd_we_n <= '1'; sd_dqm <= "11"; sd_ba <= "00"; sd_a <= (others=>'0');
when others => sd_cs_n <= '1'; sd_ras_n <= '1'; sd_cas_n <= '1'; sd_we_n <= '1'; sd_dqm <= "11"; sd_ba <= "00"; sd_a <= (others=>'0');
end case;
end if;
end process;
--------------------------------------------------------------------------------------------------- State Change Logic ---------------------------------------------------------------------------------------------------
NEXT_STATE_DECODE: process(sys_clk)
begin
if rising_edge(sys_clk) then
if sys_rst='1' then
state <= st_init_1;
else
case state is
--------------------------------- SDRAM Init ---------------------------------
when st_init_1 => -- At least 200us delay with nop command when power up (counter=0)
if sys_start='1' then
state <= st_init_2;
end if;
when st_init_2 => -- Precharge all banks command (counter=0)
state <= st_init_3;
when st_init_3 => -- tRP time needed with nop command ( min 20ns ) (counter=3)
if counter="0011" then
state <= st_init_4;
end if;
when st_init_4 => -- Auto refresh command ( min 8 times ) (rpt.)
state <= st_init_5;
when st_init_5 => -- tRC time needed with nop command ( min 65ns ) (rpt.)
if counter(2 downto 0)="100" then
if init_ref_cnt="1010" then
state <= st_init_6;
else
state <= st_init_4;
end if;
end if;
when st_init_6 => -- Mode register set command ( CL=2, BL=1 ) (counter=5)
state <= st_idle_1;
--------------------------------- IDLE STATE I ---------------------------------
when st_idle_1 => -- tMRS time needed with nop command ( min 2 clks ) (counter=0) if ref_req='1' then state <= st_idle_1_ref_1; elsif addr_wr=x"A76000" then -- 2028*5356 Words ( 20.7M Byte ) state <= st_idle_2; elsif fifo2sd_full='1' then state <= st_wr_ref_1; else state <= st_idle_1; end if;
--------------------------------- SDRAM Write ---------------------------------
when st_wr_ref_1 => -- Auto refresh command (counter=0) state <= st_wr_ref_2; when st_wr_ref_2 => -- tRC time needed with nop command ( min 65ns ) (counter=4) if counter="0100" then state <= st_wr_ref_3; end if; when st_wr_ref_3 => -- Auto refresh command (counter=5) state <= st_wr_ref_4; when st_wr_ref_4 => -- tRC time needed with nop command ( min 65ns ) (counter=9) if counter="1001" then state <= st_wr_1; end if;
when st_wr_1 => -- Active command (counter=10)
state <= st_wr_2;
when st_wr_2 => -- tRCD time needed with nop command ( min 20ns ) (counter=12)
if counter="1100" then
state <= st_wr_3;
end if;
when st_wr_3 => -- Write command (507 16-bit word) (counter=0)
if addr_wr(8 downto 0)="111111010" then
state <= st_wr_4;
end if;
when st_wr_4 => -- tRDL time needed with nop command ( min 2 clks ) (counter=3)
if counter="0011" then
state <= st_wr_5;
end if;
when st_wr_5 => -- Precharge command (counter=4)
state <= st_wr_6;
when st_wr_6 => -- tRP time needed with nop command ( min 20ns ) (counter=6)
if counter="0110" then
state <= st_idle_1;
end if;
--------------------------------- IDLE STATE II ---------------------------------
when st_idle_2 => -- idle II (counter=0) if ref_req='1' then state <= st_idle_2_ref_1; elsif addr_rd=x"A76000" then -- 2028*5356 Words ( 20.7M Byte ) state <= st_init_1; elsif sd2fifo_empty='1' then state <= st_rd_ref_1; else state <= st_idle_2; end if;
--------------------------------- SDRAM Read --------------------------------- when st_rd_ref_1 => -- Auto refresh command (counter=0) state <= st_rd_ref_2; when st_rd_ref_2 => -- tRC time needed with nop command ( min 65ns ) (counter=4) if counter="0100" then state <= st_rd_ref_3; end if; when st_rd_ref_3 => -- Auto refresh command (counter=5) state <= st_rd_ref_4; when st_rd_ref_4 => -- tRC time needed with nop command ( min 65ns ) (counter=9) if counter="1001" then state <= st_rd_1; end if;
when st_rd_1 => -- Active command (counter=10) state <= st_rd_2; when st_rd_2 => -- tRCD time needed with nop command ( min 20ns ) (counter=12) if counter="1100" then state <= st_rd_3; end if; when st_rd_3 => -- Read command (507 16-bit word) (counter=0) if addr_rd(8 downto 0)="111111010" then state <= st_rd_4; end if; when st_rd_4 => -- CAS Latency = 2 (counter=1) if counter="0001" then state <= st_rd_5; end if; when st_rd_5 => -- Precharge command (counter=2) state <= st_rd_6; when st_rd_6 => -- tRP time needed with nop command ( min 20ns ) (counter=4) if counter="0100" then state <= st_idle_2; end if;
--------------------------------- SDRAM Refresh ---------------------------------
when st_idle_1_ref_1 => -- Auto refresh command (counter=0)
state <= st_idle_1_ref_2;
when st_idle_1_ref_2 => -- tRC time needed with nop command ( min 65ns ) (counter=4)
if counter="0100" then
state <= st_idle_1;
end if;
when st_idle_2_ref_1 => -- Auto refresh command (counter=0) state <= st_idle_2_ref_2; when st_idle_2_ref_2 => -- tRC time needed with nop command ( min 65ns ) (counter=4) if counter="0100" then state <= st_idle_2; end if;
when others =>
state <= st_init_1;
end case;
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------- Counter for State Change Logic ---------------------------------------------------------------------------------------------------
process(sys_clk)
begin
if rising_edge(sys_clk) then
if state=st_init_1 or state=st_idle_1 or state=st_idle_2 or state=st_rd_3 or state=st_wr_3 then
counter <= (others=>'0');
else
counter <= counter + 1;
end if;
end if;
end process;
------------------------------------------------------------------------------------------------- Counters and logic gates for auto-refresh -------------------------------------------------------------------------------------------------process(sys_clk)beginif rising_edge(sys_clk) then if sys_rst='1' then init_ref_cnt <= (others=>'0'); elsif state=st_init_4 then init_ref_cnt <= init_ref_cnt + 1; end if;end if;end process;process(sys_clk)beginif rising_edge(sys_clk) then if (sys_rst='1' or state=st_idle_1_ref_1 or state=st_idle_2_ref_1) then ref_cnt <= (others=>'0'); else ref_cnt <= ref_cnt + 1; end if;end if;end process;process(sys_clk)beginif rising_edge(sys_clk) then if (sys_rst='1' or state=st_idle_1_ref_1 or state=st_idle_2_ref_1) then ref_req <= '0'; elsif ref_cnt=X"FF" then ref_req <= '1'; end if;end if;end process;
--------------------------------------------------------------------------------------------------- Address Logic Signal ---------------------------------------------------------------------------------------------------
process(sys_clk)beginif rising_edge(sys_clk) then if (sys_rst='1' or state=st_idle_2) then addr_wr <= (others=>'0'); elsif state=st_wr_3 then
if addr_wr(8 downto 0)="111111010" then -- Write 507 16-bit word per line addr_wr <= addr_wr + x"000006";
else
addr_wr <= addr_wr + 1;
end if; end if;end if;end process;process(sys_clk)beginif rising_edge(sys_clk) then if (sys_rst='1' or state=st_idle_1) then addr_rd <= (others=>'0'); elsif state=st_rd_3 then
if addr_rd(8 downto 0)="111111010" then -- Read 507 16-bit word per line addr_rd <= addr_rd + x"000006"; else addr_rd <= addr_rd + 1;
end if; end if;end if;end process;
--------------------------------------------------------------------------------------------------- FIFO Interface Signals ---------------------------------------------------------------------------------------------------
process(sys_clk)beginif rising_edge(sys_clk) then if sys_rst='1' then fifo2sd_en <= '0'; elsif (state=st_wr_2 and counter="1100") then fifo2sd_en <= '1'; elsif (state=st_wr_3 and addr_wr(8 downto 0)="111111010") then -- Write 507 16-bit word per line fifo2sd_en <= '0'; end if;end if;end process;process(sys_clk)beginif rising_edge(sys_clk) then if sys_rst='1' then sd2fifo_en <= '0';
elsif (state=st_rd_3 and addr_rd(8 downto 0)="000000010") then sd2fifo_en <= '1';
elsif state=st_rd_5 then sd2fifo_en <= '0'; end if;end if;end process;
--------------------------------------------------------------------------------------------------- Internal Signal and Static Signal Output Logic ---------------------------------------------------------------------------------------------------
process(sys_clk)beginif rising_edge(sys_clk) then if (state=st_wr_2 or state=st_wr_3 or state=st_wr_4) then dq_tri_en <= '1'; else dq_tri_en <= '0'; end if;end if;end process;
sd_cke <= '1';
BUFG_inst : BUFGport map ( O => sd_ck, -- Clock buffer output I => sd_ck_i -- Clock buffer input );
sd_ck_i <= not sys_clk;
end Behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -