⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 example16-15.vhd

📁 vhdl 实例 通过实例学习vhdl 编程
💻 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 + -