📄 example16-15.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_a,next_state_a: STATES;
SIGNAL current_state_b,next_state_b: STATES;
SIGNAL dram_addr_a:std_logic_vector(9 downto 0);
SIGNAL dram_addr_b:std_logic_vector(9 downto 0);
SIGNAL ras_a:std_logic_vector(1 downto 0);
SIGNAL ras_b:std_logic_vector(1 downto 0);
SIGNAL cas_a:std_logic_vector(3 downto 0);
SIGNAL cas_b:std_logic_vector(3 downto 0);
SIGNAL we_a:std_logic;
SIGNAL we_b:std_logic;
SIGNAL ack_a:std_logic;
SIGNAL ack_b:std_logic;
SIGNAL ready_a:std_logic;
SIGNAL ready_b:std_logic;
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_a:PROCESS(row_addr,col_addr,current_state_a)
BEGIN
IF current_state_a=row_address or current_state_a=ras_assert THEN
dram_addr_a<=row_addr;
ELSE
dram_addr_a<=col_addr;
END IF;
END PROCESS;
multiplexer_b:PROCESS(row_addr,col_addr,current_state_b)
BEGIN
IF current_state_b=row_address or current_state_b=ras_assert THEN
dram_addr_b<=row_addr;
ELSE
dram_addr_b<=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_a/=refresh0))
ELSE '0';
--DRAM Finite State Machine a
state_a:PROCESS(current_state_b,refresh_req,addr_strobe,match)
BEGIN
CASE current_state_b IS --next state of FSMa depends on current state of FSMb
WHEN idle=>
IF refresh_req='1' THEN
next_state_a<=refresh0;
ELSIF addr_strobe='0' THEN
next_state_a<=address_detect;
ELSE
next_state_a<=idle;
END IF;
WHEN address_detect=>
IF match='1' THEN
next_state_a<=row_address;
ELSE
next_state_a<=idle;
END IF;
WHEN row_address=>
next_state_a<=ras_assert;
WHEN ras_assert=>
next_state_a<=col_address;
WHEN col_address=>
next_state_a<=cas_assert;
WHEN cas_assert=>
next_state_a<=data_ready;
WHEN data_ready=>
next_state_a<=wait_state;
WHEN wait_state=>
next_state_a<=idle;
WHEN refresh0=>
next_state_a<=refresh1;
WHEN refresh1=>
next_state_a<=idle;
WHEN others=>NULL;
END CASE;
END PROCESS;
locked_a:PROCESS(clk,reset)
BEGIN
IF reset='1' THEN
current_state_a<=idle;
ELSIF clk'EVENT and clk='1' THEN
current_state_a<=next_state_a;
END IF;
END PROCESS;
WITH current_state_a SELECT
cas_a<="0000" WHEN cas_assert |data_ready|wait_state|refresh0|refresh1,
"1111" WHEN others;
ras_a<= "00" WHEN (current_state_a=ras_assert or current_state_a=col_address or
current_state_a=cas_assert or current_state_a=data_ready or
current_state_a=wait_state) and stored(20)='1'
ELSE "10" WHEN (current_state_a=ras_assert or current_state_a=col_address or
current_state_a=cas_assert or current_state_a=data_ready or
current_state_a=wait_state) and stored(20)='0'
ELSE "11";
we_a<='0' WHEN (current_state_a=col_address or current_state_a=cas_assert or
current_state_a=data_ready) and read='0' ELSE '1';
ack_a<='0' WHEN current_state_a=address_detect and match='1' ELSE '1';
ready_a<='0' WHEN read='1' and (current_state_a=data_ready or
current_state_a=wait_state) ELSE '1';
--DRAM Finite State Machine b
state_b:PROCESS(current_state_a,refresh_req,addr_strobe,match)
BEGIN
CASE current_state_a IS --next state of FSMb depends on current state of FSMa
WHEN idle=>
IF refresh_req='1' THEN
next_state_b<=refresh0;
ELSIF addr_strobe='0' THEN
next_state_b<=address_detect;
ELSE
next_state_b<=idle;
END IF;
WHEN address_detect=>
IF match='1' THEN
next_state_b<=row_address;
ELSE
next_state_b<=idle;
END IF;
WHEN row_address=>
next_state_b<=ras_assert;
WHEN ras_assert=>
next_state_b<=col_address;
WHEN col_address=>
next_state_b<=cas_assert;
WHEN cas_assert=>
next_state_b<=data_ready;
WHEN data_ready=>
next_state_b<=wait_state;
WHEN wait_state=>
next_state_b<=idle;
WHEN refresh0=>
next_state_b<=refresh1;
WHEN refresh1=>
next_state_b<=idle;
WHEN others=>NULL;
END CASE;
END PROCESS;
locked_b:PROCESS(clk,reset)
BEGIN
IF reset='1' THEN
current_state_b<=idle;
ELSIF clk'EVENT and clk='1' THEN
current_state_b<=next_state_b;
END IF;
END PROCESS;
WITH current_state_b SELECT
cas_b<="0000" WHEN cas_assert |data_ready|wait_state|refresh0|refresh1,
"1111" WHEN others;
ras_b<= "00" WHEN (current_state_b=ras_assert or current_state_b=col_address or
current_state_b=cas_assert or current_state_b=data_ready or
current_state_b=wait_state) and stored(20)='1'
ELSE "10" WHEN (current_state_b=ras_assert or current_state_b=col_address or
current_state_b=cas_assert or current_state_b=data_ready or
current_state_b=wait_state) and stored(20)='0'
ELSE "11";
we_b<='0' WHEN (current_state_b=col_address or current_state_b=cas_assert or
current_state_b=data_ready) and read='0' ELSE '1';
ack_b<='0' WHEN current_state_b=address_detect and match='1' ELSE '1';
ready_a<='0' WHEN read='1' and (current_state_b=data_ready or
current_state_b=wait_state) ELSE '1';
--output multiplexer
cas<=cas_a WHEN clk='1' ELSE cas_b;
ras<=ras_a WHEN clk='1' ELSE ras_b;
we<=we_a WHEN clk='1' ELSE we_b;
ack<=ack_a WHEN clk='1' ELSE ack_b;
dram_addr<=dram_addr_a WHEN clk='1' ELSE dram_addr_b;
ready<=ready_a WHEN clk='1' ELSE ready_b;
END behave;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -