📄 sdr_ctrl.vhd
字号:
if startup_pending = '1' then
if startup_timer < tSTARTUP_NOP_CYCLES then
startup_timer <= startup_timer + 1;
state <= initialize after hold_time;
else
state <= precharge after hold_time;
end if;
elsif refresh_req = '1' and aref_enable = '1' then
refresh_done_flg <= '1';
state <= auto_refresh after hold_time;
elsif nAS_WAITING = '1' then
aref_enable <= '0';
refresh_done_flg <= '0';
state <= active after hold_time;
else
refresh_done_flg <= '0';
end if;
--------------------------
-- PRECHARGE command
--------------------------
when precharge =>
nCS <= '0' after hold_time;
nRAS <= '0' after hold_time;
nCAS <= '1' after hold_time;
nWE <= '0' after hold_time;
A(10) <= '1'; -- precharge all banks
if execute_nop = '1' then
nCS <= '0' after hold_time;
nRAS <= '1' after hold_time;
nCAS <= '1' after hold_time;
nWE <= '1' after hold_time;
end if;
-- if burst size 1 or 2
if burst_size(2 downto 1) = "00" then
nDTACK <= '1';
end if;
if wait_counter < tRP_CYCLES then
wait_counter <= wait_counter + 1;
execute_nop <= '1';
else
execute_nop <= '0';
wait_counter <= 0;
if startup_pending = '1' then
state <= auto_refresh after hold_time;
else
state <= nop after hold_time;
end if;
end if;
-------------------------
-- AUTO REFRESH command
-------------------------
when auto_refresh =>
nCS <= '0' after hold_time;
nRAS <= '0' after hold_time;
nCAS <= '0' after hold_time;
nWE <= '1' after hold_time;
if execute_nop = '1' then
nCS <= '0' after hold_time;
nRAS <= '1' after hold_time;
nCAS <= '1' after hold_time;
nWE <= '1' after hold_time;
end if;
if wait_counter < (tRFC_CYCLES-1)+conv_integer(startup_pending) then
wait_counter <= wait_counter + 1;
execute_nop <= '1';
else
execute_nop <= '0';
wait_counter <= 0;
if init_refreshes < init_ref_cycles-1 then
init_refreshes <= init_refreshes + 1;
else
if startup_pending = '1' then
state <= set_ModeRegister after hold_time;
else
state <= nop after hold_time;
end if;
end if;
end if;
-------------------------
-- ACTIVE command
-------------------------
when active =>
nCS <= '0' after hold_time;
nRAS <= '0' after hold_time;
nCAS <= '1' after hold_time;
nWE <= '1' after hold_time;
A <= row_addr after hold_time;
BS <= bank_numb after hold_time;
if execute_nop = '1' then
nCS <= '0' after hold_time;
nRAS <= '1' after hold_time;
nCAS <= '1' after hold_time;
nWE <= '1' after hold_time;
end if;
if wait_counter < tRCD_CYCLES then
wait_counter <= wait_counter + 1;
execute_nop <= '1';
else
execute_nop <= '0';
wait_counter <= 0;
if WnR_S = '1' then
state <= write after hold_time;
nDTACK <= '0' after hold_time;
else
state <= read after hold_time;
end if;
end if;
------------------------
-- READ command
------------------------
when read =>
nCS <= '0' after hold_time;
nRAS <= '1' after hold_time;
nCAS <= '0' after hold_time;
nWE <= '1' after hold_time;
DQM <= nLBE_s after hold_time;
A(column_length-1 downto 0) <= col_addr after hold_time;
A(10) <= auto_precharge;
if execute_nop = '1' then
nCS <= '0' after hold_time;
nRAS <= '1' after hold_time;
nCAS <= '1' after hold_time;
nWE <= '1' after hold_time;
end if;
if CAS_counter < CAS_LATENCY then
CAS_counter <= CAS_counter + 1;
execute_nop <= '1';
else
if burst_size = "000" then
state <= precharge after hold_time;
aref_enable <= '1';
execute_nop <= '0';
nDTACK <= '0' after hold_time;
else
CAS_counter <= 0;
execute_nop <= '0';
nDTACK <= '0' after hold_time;
state <= read_data after hold_time;
end if;
end if;
case burst_size is
-- burst size of 2
when "001" =>
wait_counter <= 5;
-- burst size of 4
when "010" =>
wait_counter <= 4;
-- burst size of 8 or no burst
when others =>
wait_counter <= 0;
end case;
------------------------
-- reading data
------------------------
when read_data =>
if wait_counter = 5 then
state <= precharge after hold_time;
aref_enable <= '1';
wait_counter <= 0;
else
wait_counter <= wait_counter + 1;
end if;
------------------------
-- WRITE command
------------------------
when write =>
nCS <= '0' after hold_time;
nRAS <= '1' after hold_time;
nCAS <= '0' after hold_time;
nWE <= '0' after hold_time;
DQM <= nLBE_s after hold_time;
A(10) <= auto_precharge;
A(column_length+1 downto column_length) <= "00" after hold_time;
A(column_length-1 downto 0) <= col_addr after hold_time;
nDTACK <= '1' after hold_time;
if execute_nop = '1' then
nCS <= '0' after hold_time;
nRAS <= '1' after hold_time;
nCAS <= '1' after hold_time;
nWE <= '1' after hold_time;
end if;
if wait_counter < tWR_CYCLES then
wait_counter <= wait_counter + 1;
execute_nop <= '1';
else
execute_nop <= '0';
wait_counter <= 0;
aref_enable <= '1';
state <= precharge after hold_time;
end if;
when others =>
nDTACK <= '1' after hold_time;
state <= nop;
nCS <= '1';
nRAS <= '1';
nCAS <= '1';
nWE <= '1';
BS <= (others => '0');
CKE <= '1';
DQM <= (others => '1');
A <= (others => '0');
end case;
end if;
end process;
-- generate refresh counts and requests
refresh_process: process (CLK, nRST) is
begin
if nRST = '0' then
refresh_timer <= 0;
refresh_req <= '0';
elsif rising_edge(CLK) then
if refresh_timer < tREF_CYCLES then
refresh_req <= '0';
refresh_timer <= refresh_timer + 1;
elsif refresh_done_flg = '1' then
refresh_req <= '0';
refresh_timer <= 0;
else
refresh_req <= '1';
end if;
end if;
end process refresh_process;
end SDR_CTRL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -