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

📄 flashctrl.vhd

📁 VHDL编写的flash控制器源代码.包含testbench。
💻 VHD
📖 第 1 页 / 共 2 页
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

--This is a simplified version of Flash Control. Only a subset of flash control is implemented. 
--The following operation are supported:
entity FlashCtrl is
	generic(ADDRESS_WIDTH	: integer range 0 to 32 := 24;
		DATA_WIDTH	: integer range 0 to 16 := 8;
		READ_CYCLES 	: integer range 0 to 15 := 9);
	port(
		reset 		: in std_logic; --reset signal. 
		clk 		: in std_logic; --60MHz Clock
	
		--Computer Interface:
		--In 8 bit flash control, the command is 16bit, thus we need 2 wrCmdByte operation to send one command
		CS			: in std_logic;
		wrCmdByte	: in std_logic;
		CmdByte		: in std_logic_vector(7 downto 0);
		
		--test pins:
		wrEPPCmdOut : out std_logic;
		EPPCmdWordOut : out std_logic_vector(15 downto 0);
		
		--
		--Return value to computer
		DataToEPP	: out std_logic_vector(7 downto 0);
		
		--LookupTable Interface:
		rdLUT		: in std_logic;
		LUTAddr		: in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
		LUTData		: out std_logic_vector(DATA_WIDTH-1 downto 0);
		
		--Flash Memory Interface
		FlashAddr 	: out std_logic_vector(ADDRESS_WIDTH-1 downto 0);
		FlashDQ 	: inout std_logic_vector(DATA_WIDTH-1 downto 0);
		CENeg 		: OUT    std_ulogic := 'U';
		OENeg 		: OUT    std_ulogic := 'U';
		WENeg 		: OUT    std_ulogic := 'U';
		RESETNeg 	: OUT    std_ulogic := 'U';
		WPNeg 		: OUT    std_ulogic := 'U'; --WP#/ACC
		BYTENeg 	: OUT    std_ulogic := 'U';
		RY 		: IN   std_ulogic := 'U'  --RY/BY#
	);
end entity FlashCtrl;

architecture arch1 of FlashCtrl is

	component dffsr is --synchronous reset
	port(
			clk: in std_logic;
			sreset : in std_logic;
			d: in std_logic;
			q: out std_logic);
	end component;

	component lpm_fifo16x16 IS
		PORT
		(
			aclr		: IN STD_LOGIC ;
			clock		: IN STD_LOGIC ;
			data		: IN STD_LOGIC_VECTOR (15 DOWNTO 0);
			rdreq		: IN STD_LOGIC ;
			wrreq		: IN STD_LOGIC ;
			empty		: OUT STD_LOGIC ;
			full		: OUT STD_LOGIC ;
			q		: OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
			usedw		: OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
		);
	END component;
	
	--Signals for store command from EPP
	signal CmdFlag: std_logic; --This is the flag to show wich byte of EPPCmdWord is to be written
	signal EPPCmdWord : std_Logic_vector(15 downto 0); --This is the command get from EPP, all the other operation are controlled by this
				--it can be split to two part: ControlByte(7 downto 0) and DataByte(7 downto 0):
	signal ControlByte, DataByte : std_logic_vector(7 downto 0);
	signal wrEPPCmd : std_logic;
	
	--Fifos: Here we need two fifo, Read Fifo and Write Fifo:
	--1. WriteFifo:
	signal WriteFifoAclr, WriteFifoClock, WriteFifoRdReq, WriteFifoWrreq, WriteFifoEmpty, WriteFifoFull: std_logic;
	signal WriteFifoUsedw: std_logic_vector(3 downto 0);
	signal WriteFifoData, WriteFifoQ : std_logic_vector(15 downto 0);
	signal WriteFifoStatus : std_logic_vector(5 downto 0);
	--2. ReadFifo:
	signal ReadFifoAclr, ReadFifoClock, ReadFifoRdreq, ReadFifoWrreq, ReadFifoEmpty, ReadFifoFull : std_logic;
	signal ReadFifoUsedw: std_logic_vector(3 downto 0);
	signal ReadFifoData, ReadFifoQ : std_logic_vector(15 downto 0);
	signal ReadFifoStatus : std_logic_vector(5 downto 0);
	
	--Flash Memory Control Statemachine
	type FlashCtrlStateTYPE is(IDLE, SingleRead, BlockRead, BlockWrite, SECTORERASE, CHIPERASE, CHIPRESET);
	signal FlashState : FlashCtrlStateTYPE;
	signal FlashStateStatus : std_logic_vector(7 downto 0);
	--Signal for READ Flash Memroy(both SingleRead and BlockRead):
	signal ReadFlashTimer : integer range 0 to 15;
	signal ReadFlashCounter : integer range 0 to 16;
	signal TargetFlashMemPageAddr : std_logic_vector(ADDRESS_WIDTH-1 downto 0); --This is the Flash Memory Page Address that will be operated,
				--Page address means that the lower 4bit is '0';
	--Signal for Write Flash Memory
	signal WriteTimer : integer range 0 to 511;
	signal SingleWriteTimer : integer range 0 to 15;
	signal WriteFlashCounter: integer range 0 to 16;
	signal TargetFlashMemSectorAddr : std_logic_vector(ADDRESS_WIDTH-1 downto 0); -- This is the Sector Address that is needed for BlockWrite
				--SECTORERASE and CHIPERASE operation
	

	
	
begin


wrEPPCmdOut <= wrEPPCmd;
EPPCmdWordOut <= EPPCmdWord;
---------------------------------------------------------------------------------------------------------
--get Command from EPPInterface
---------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------
--get Command from EPPInterface
---------------------------------------------------------------------------------------------------------
gen_EPPCmdWord: process(reset,clk)
begin
	if reset='1' then
		CmdFlag <= '0';
		EPPCmdWord <= (others => '0');
		wrEPPCmd <= '0';
	elsif clk'event and clk='1' then
		if CS = '1' and wrCmdByte = '1' then
			CmdFlag <= not CmdFlag;
			if CmdFlag = '1' then
				wrEPPCmd <= '1';
			else
				wrEPPCmd <= '0';
			end if;
			case CmdFlag is
				when '0' => EPPCmdWord(7 downto 0) <= CmdByte;
				when '1' => EPPCmdWord(15 downto 8) <= CmdByte;
				when others =>
			end case;
		else
			wrEPPCmd <= '0';
		end if;
	end if;
end process;
ControlByte(7 downto 0) <= EPPCmdWord(15 downto 8);
DataByte(7 downto 0) <= EPPCmdWord(7 downto 0);

---------------------------------------------------------------------------------------------------------
--WriteFifo Control
--WriteFifo use ControlByte address space 0x50~0x5F
---------------------------------------------------------------------------------------------------------
WriteFifo: lpm_fifo16x16
	port map(
		aclr => WriteFifoAclr,
		clock => WriteFifoClock,
		data => WriteFifoData,
		rdreq => WriteFifoRdreq,
		wrreq => WriteFifoWrreq,
		empty => WriteFifoEmpty,
		full => WriteFifoFull,
		q => WriteFifoQ,
		usedw => WriteFifoUsedw);

WriteFifoClock <= clk;
WriteFifoStatus <= WriteFifoEmpty & WriteFifoFull & WriteFifoUsedw;
gen_WriteFifoAclr: process(reset,clk)
begin
	if reset = '1' then
		WriteFifoAclr <= '1';
	elsif clk'event and clk='1' then
		if wrEPPCmd='1' and ControlByte = X"50" then
			WriteFifoAclr <= '1';
		else
			WriteFifoAclr <= '0';
		end if;
	end if;
end process;
gen_WriteFifoData : process(reset,clk)
begin
	if reset = '1' then
		WriteFifoWrreq <= '0';
		WriteFifoData <= (others => '0');
	elsif clk'event and clk = '1' then
		--wrEPPCmd is a one clock cycle wide pulse, thus the width of WriteFifoWrreq will be 1 clock cycle	
		if wrEPPCmd = '1' then 
			case ControlByte is
				when X"51" =>
					WriteFifoData(7 downto 0) <= DataByte;
				when X"52" =>
					WriteFifoWrreq <= '1';
					WriteFifoData(15 downto 8) <= DataByte;
				when others =>
					WriteFifoWrreq <= '0';
			end case;
		else
			WriteFifoWrreq <= '0';
		end if;
	end if;
end process;


---------------------------------------------------------------------------------------------------------
--ReadFifo Control
--ReadFifo uses ControlByte address space 0x60~0x6F
---------------------------------------------------------------------------------------------------------
ReadFifo: lpm_fifo16x16
	port map(
		aclr => ReadFifoAclr,
		clock => ReadFifoClock,
		data => ReadFifoData,
		rdreq => ReadFifoRdreq,
		wrreq => ReadFifoWrreq,
		empty => ReadFifoEmpty,
		full => ReadFifoFull,
		q => ReadFifoQ,
		usedw => ReadFifoUsedw);
ReadFifoClock <= clk;
ReadFifoStatus <= ReadFifoEmpty & ReadFifoFull & ReadFifoUsedw;
gen_ReadFifoAclk : process(reset,clk)
begin
	if reset = '1' then
		ReadFifoAclr <= '1';
	elsif clk'event and clk='1' then
		if wrEPPCmd = '1' and ControlByte <= X"60" then
			ReadFifoAclr <= '1';
		else
			ReadFifoAclr <= '0';
		end if;
	end if;
end process;
gen_ReadFifoRdreq : process(reset,clk)
begin
	if reset = '1' then
		ReadFifoRdreq <= '0';
	elsif clk'event and clk='1' then
		if wrEPPCmd = '1' and ControlByte <= X"61" then
			ReadFifoRdreq <= '1';
		else
			ReadFifoRdreq <= '0';
		end if;
	end if;
end process;

---------------------------------------------------------------------------------------------------------
--Target Address:
--TargetFlashMemPageAddr and TargetFlashMemSectorAddr
---------------------------------------------------------------------------------------------------------
gen_TargetFlashAddr : process(reset,clk)
begin
	if reset = '1' then
		TargetFlashMemPageAddr <= (others => '0');
		TargetFlashMemSectorAddr <= (others => '0');
	elsif clk'event and clk='1' then
		if wrEPPCmd = '1' then
			case ControlByte is 
				when X"19" => TargetFlashMemPageAddr(7 downto 0) <= DataByte;
				when X"1A" => TargetFlashMemPageAddr(15 downto 8) <= DataByte;
				when X"1B" => TargetFlashMemPageAddr(23 downto 16) <= DataByte;
				when X"1C" => TargetFlashMemSectorAddr(7 downto 0) <= DataByte;
				when X"1D" => TargetFlashMemSectorAddr(15 downto 8) <= DataByte;
				when X"1E" => TargetFlashMemSectorAddr(23 downto 16) <= DataByte;
				when others =>
			end case;
		end if;
	end if;
end process;

----------------------------------------------------------------------------------------------------------
--ReadOut
----------------------------------------------------------------------------------------------------------
gen_DataToEPP: process(reset,clk)
begin
	if reset = '1' then
		DataToEPP <= (others => '0');
	elsif clk'event and clk = '1' then
		if wrEPPCmd = '1' then
			case ControlByte is
				when X"53" => --Status of WriteFifo
					DataToEPP(5 downto 0) <= WriteFifoStatus(5 downto 0);
					DataToEPP(7 downto 6) <= (others => '0');
				when X"62" =>
					DataToEPP <= ReadFifoQ(7 downto 0);
				when X"63" =>
					DataToEPP <= ReadFifoQ(15 downto 8); --Even for 8bit operation, since we use 16bit Fifo, still we have ReadFifoQ(15 downto 8),
											--it will be X"00" in 8 bit mode;
				when X"64" => --Status of ReadFifo
					DataToEPP(5 downto 0) <= ReadFifoStatus(5 downto 0);
					DataToEPP(7 downto 6) <= (others => '0');
				when X"17" => --FlashStateStatus 
					DataToEPP <= FlashStateStatus;
				when others =>
			end case;
		end if;
	end if;
end process;
				
					
---------------------------------------------------------------------------------------------------------
--State Machine:
---------------------------------------------------------------------------------------------------------
genFlashState: process(reset,clk)
begin
	if reset = '1' then
		FlashState <= IDLE;
		CENeg <= '1';
		WENeg <= '1';
		OENeg <= '1';
		RESETNeg <= '1';
		--Sig for rdLUT:
		ReadFlashTimer <= 0;
		ReadFlashCounter <= 0;
		--Sig for Write and ERASE
		WriteTimer <= 0;
		SingleWriteTimer <= 0;
		WriteFlashCounter <= 0;
		LUTData <= (others => 'Z');
		FlashAddr <= (others => '0');
		ReadFifoData <= (others => '0');
		WriteFifoRdReq <= '0';
		ReadFifoWrreq <= '0';
		FlashDQ <= (others => 'Z');
		FlashStateStatus <= X"00";
	elsif clk'event and clk='1' then
		case FlashState is
			when IDLE =>
				CENeg <= '1';
				WENeg <= '1';
				OENeg <= '1';
				RESETNeg <= '1';
				ReadFlashTimer <= 0;
				ReadFlashCounter <= 0;
				WriteTimer <= 0;
				SingleWriteTimer <= 0;
				WriteFlashCounter <= 0;
				LUTData <= (others => 'Z');
				FlashAddr <= (others => '0');
				FlashDQ <= (others => 'Z');
				if wrEPPCmd = '1' then
					case ControlByte is
						when X"11" =>
							FlashState <= SingleRead;
						when X"12" =>
							FlashState <= BlockRead;
						when X"13" =>
							FlashState <= BlockWrite;
						when X"14" =>
							FlashState <= SECTORERASE;
						when X"15" =>
							FlashState <= CHIPERASE;
						when X"16" =>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -