📄 example16-14.vhd
字号:
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;
ENTITY dram_controller IS
PORT (
addr: IN std_logic_vector (31 downto 0);--system address input
clk: IN std_logic;
addr_strobe: IN std_logic;
read_write: IN std_logic;
reset: IN std_logic;
ack: OUT std_logic;
we: OUT std_logic;
ready: OUT std_logic;
dram_addr: OUT std_logic_vector (9 downto 0);
ras: OUT std_logic_vector (1 downto 0);--row address strobe
cas: OUT std_logic_vector (3 downto 0)--column address strobe
);
END dram_controller;
ARCHITECTURE behave OF dram_controller IS
TYPE STATES IS (idle,address_detect,row_address,ras_assert,col_address,
cas_assert,data_ready,wait_state,refresh0,refresh1);
SIGNAL current_state,next_state: STATES;
SIGNAL stored: std_logic_vector(31 downto 0);--stored address
SIGNAL refresh_timer: std_logic_vector(8 downto 0);--refresh timer
SIGNAL refresh_req: std_logic;
SIGNAL match: std_logic;--address match
SIGNAL read: std_logic;--stored read_write signal
--synthesis parameter for row and column address
ALIAS row_addr: std_logic_vector(9 downto 0) IS stored(19 downto 10);
ALIAS col_addr: std_logic_vector(9 downto 0) IS stored(9 downto 0);
BEGIN
--get address
get:PROCESS(clk,reset)
BEGIN
IF reset='1' THEN
stored<=(others=>'0');
read<='0';
ELSIF clk'EVENT and clk='1' THEN
IF addr_strobe='0' THEN
stored<=addr;
read<=read_write;
END IF;
END IF;
END PROCESS;
--address comparator which determines if memory is being accessed
match<='1' WHEN stored(31 downto 21)="00000000000" ELSE '0';
--address multiplexer which selects the row,column,or refresh address
multiplexer:PROCESS(row_addr,col_addr,current_state)
BEGIN
IF current_state=row_address or current_state=ras_assert THEN
dram_addr<=row_addr;
ELSE
dram_addr<=col_addr;
END IF;
END PROCESS;
--refresh counter and timer
--refresh counter which is used to initiate refresh cycles
--a refresh request is generated every 312 clock cycles
--refresh_req is asserted until a refresh cycle begins
p3:PROCESS(clk,reset)
BEGIN
IF reset='1' THEN
refresh_timer<=(others=>'0');
ELSIF clk'EVENT and clk='1' THEN
IF refresh_timer="100111000" THEN
refresh_timer<=(others=>'0');
ELSE
refresh_timer<=refresh_timer+1;
END IF;
END IF;
END PROCESS;
refresh_req<='1' WHEN (refresh_timer="100111000" or (refresh_req='1' and
current_state/=refresh0))
ELSE '0';
--DRAM Finite State Machine
state_p:PROCESS(current_state,refresh_req,addr_strobe,match)
BEGIN
CASE current_state IS
WHEN idle=>
IF refresh_req='1' THEN
next_state<=refresh0;
ELSIF addr_strobe='0' THEN
next_state<=address_detect;
ELSE
next_state<=idle;
END IF;
WHEN address_detect=>
IF match='1' THEN
next_state<=row_address;
ELSE
next_state<=idle;
END IF;
WHEN row_address=>
next_state<=ras_assert;
WHEN ras_assert=>
next_state<=col_address;
WHEN col_address=>
next_state<=cas_assert;
WHEN cas_assert=>
next_state<=data_ready;
WHEN data_ready=>
next_state<=wait_state;
WHEN wait_state=>
next_state<=idle;
WHEN refresh0=>
next_state<=refresh1;
WHEN refresh1=>
next_state<=idle;
WHEN others=>NULL;
END CASE;
END PROCESS;
locked:PROCESS(clk,reset)
BEGIN
IF reset='1' THEN
current_state<=idle;
ELSIF clk'EVENT and clk='1' THEN
current_state<=next_state;
END IF;
END PROCESS;
WITH current_state SELECT
cas<="0000" WHEN cas_assert |data_ready|wait_state|refresh0|refresh1,
"1111" WHEN others;
ras<= "00" WHEN (current_state=ras_assert or current_state=col_address or
current_state=cas_assert or current_state=data_ready or
current_state=wait_state) and stored(20)='1'
ELSE "10" WHEN (current_state=ras_assert or current_state=col_address or
current_state=cas_assert or current_state=data_ready or
current_state=wait_state) and stored(20)='0'
ELSE "11";
we<='0' WHEN (current_state=col_address or current_state=cas_assert or
current_state=data_ready) and read='0' ELSE '1';
ack<='0' WHEN current_state=address_detect and match='1' ELSE '1';
ready<='0' WHEN read='1' and (current_state=data_ready or
current_state=wait_state) ELSE '1';
END behave;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -