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

📄 litenandfsm.vhdl

📁 NAND Flash Controller & ECC VHDL Code
💻 VHDL
📖 第 1 页 / 共 2 页
字号:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

--  Uncomment the following lines to use the declarations that are
--  provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;

entity LITEnandFSM is
	generic(
		ErrorFetchCommand: std_logic_vector(7 downto 0) := x"23"
		);
	Port(
		DEBUGvector : out std_logic_vector (3 downto 0);

		-- disabling ECC
		enableECCmodule: in std_logic;
		-- The basics of synchronous design
    		clk : in std_logic;
    		clkDIVx3 : in std_logic;
		Reset_L : in std_logic;

    		-- Output interface
          hostIOin     : in std_logic_vector (7 downto 0); 
          hostIOout     : out std_logic_vector (7 downto 0); 
          hostIOdrv    : out std_logic; 
    		--hostIO : inout std_logic_vector(7 downto 0);
    		hostCE_L : in std_logic;
          hostCLE_H : in std_logic;
          hostALE_H : in std_logic;
          hostWE_L : in std_logic;
          hostRE_L : in std_logic;
          hostWP_L : in std_logic;
          intPRE : in std_logic;
          hostRB_L : out std_logic;
          interrINT_H : out std_logic;

		-- NAND flash Interface
          nandCE_L : out std_logic;
          nandCLE_H : out std_logic;
          nandALE_H : out std_logic;
          nandWE_L : out std_logic;
          nandRE_L : out std_logic;
          nandWP_L : out std_logic;
          nandPRE : out std_logic;
          nandRB_L : in std_logic;
    		nandIO : inout std_logic_vector(7 downto 0);
		 
		-- ECC state machine control
		ResetECCgen : out std_logic;
		EnableECCgen: out std_logic;
		ECCgenCNT: out std_logic_vector(8 downto 0);

		-- CounterCONTROL
		count12BIT : out std_logic_vector(11 downto 0);

		-- Interrupt required or not
		NeedINT : in std_logic;

		REen_OUT : out std_logic;

		-- Address output for internal 56 bit signal
		ADDR : out std_logic_vector(2 downto 0);

		-- For outputting to the tristate
		HAMMING8bitin: in std_logic_vector(7 downto 0);
		ErrorLOCations: in std_logic_vector(7 downto 0);
		

		loadERRlocERRORS: out std_logic;
					 
		dataFORecc: out std_logic_vector(7 downto 0);
		STATEvec: out std_logic_vector(3 downto 0)

		 );
end LITEnandFSM;

architecture syn of LITEnandFSM is
	type state is (Start, 
				ReadNAND, ReadNANDwaitforRB, ReadECCcalc, 
				ReadECCfromNAND,
				ProgramNAND, ProgramNANDaddr, ProgramNANDeccCALC,
				ProgramNANDeccwrite, ThrowINT,
				ProgramNANDfillinOther, ProgramNANDbufST0,
				ProgramNANDbufST1, ProgramNANDbufST2, ProgramNANDbufST3,
				ProgramNANDcmd10h, FetchERRORS, 
				FetchERRORS_waitforRE);
				--FetchERRORSread,
	signal cSTATE, nextSTATE: state;
	signal ResetCOUNTER_L, incCOUNT: std_logic;

	-- TUG the lines signals
	signal cntTUG: std_logic_vector(2 downto 0);
	signal ResetTUGthelines, TUGthelines: std_logic;

	signal Done2100Bytes: std_logic;

	signal firstVAL: std_logic;
	--ONEdelayedRE,, secondVAL: std_logic;
	-- Tristate buffer control
	signal nandIOtempVAL: std_logic_vector(7 downto 0);
	signal HammingINmuxSEL, triSTATEnandIO : std_logic;
	-- whtHOSTio, HAMMINGtoNANDsel, REstatus, 
	signal intIO : std_logic_vector(7 downto 0);
    	signal intCE_L, intCLE_H, intALE_H, intWE_L, intRE_L, intWP_L,
			intRB_L : std_logic;
	-- signal to make intIO 0xFF so that the extra writes can be done
	signal FFintIO, SELintIO10: std_logic;
	-- registers for double latching the signals
	signal hostIOin_tmp: std_logic_vector(7 downto 0);
	signal hostCE_L_tmp, hostCLE_H_tmp, hostALE_H_tmp, hostWE_L_tmp,
			hostRE_L_tmp, hostWP_L_tmp, hostRB_L_tmp:
				std_logic;
	signal internal_COUNT : std_logic_vector(11 downto 0);
	signal incrADDR_errLOC, errlocADDRsel, ECCgenCNTsel: std_logic;
	signal SHOOTenable, internal_REGeccgen : std_logic;

begin

count12BIT <= internal_COUNT;
nandPRE <= intPRE;

REen_OUT <= incrADDR_errLOC;

RisingEDGEdetctECCgen: process(clk, SHOOTenable)
	--variable internal_REGeccgen: std_logic;
begin
	if(rising_edge(clk)) then
		if(Reset_L = '0') then
			internal_REGeccgen <= '1';
		else
			internal_REGeccgen <= SHOOTenable;
		end if;

		if(Reset_L = '0') then
			EnableECCgen <= '0';
		else
			if(SHOOTenable = '1' and internal_REGeccgen = '0') then
				EnableECCgen <= '1';
			else
				EnableECCgen <= '0';
			end if;
		end if;

	end if;
end process RisingEDGEdetctECCgen;
CountUP: process(clk, ResetCOUNTER_L, incCOUNT, internal_COUNT, errlocADDRsel,
				ECCgenCNTsel)
	variable internal_REG: std_logic;
	variable refCNT: std_logic_vector(3 downto 0);
begin

	if(rising_edge(clk)) then
		if(ResetCOUNTER_L = '0') then
			internal_COUNT <= X"FFF";
			internal_REG := '0';
		elsif(incCOUNT = '1' and internal_REG = '0') then
			internal_COUNT <= internal_COUNT + '1';
			internal_REG := '1';
		elsif(incCOUNT = '0') then
			internal_REG := '0';
		end if;
	end if;

	if(rising_edge(clk)) then
		if(Done2100Bytes = '0') then
			refCNT := "0000";
		else
			if(incrADDR_errLOC = '1') then
				refCNT := refCNT + 1;
			end if;
			if(refCNT(1 downto 0) = "11" and TUGthelines = '0') then
				refCNT := refCNT + "0001";
			end if;
			loadERRlocERRORS <= incrADDR_errLOC;
			--if(refCNT(1 downto 0) = "10") then
			--	loadERRlocERRORS <= '1';
			--else
			--	loadERRlocERRORS <= '0';
			--end if;
		end if;
	end if;
	if(errlocADDRsel = '0') then
		ADDR <= refCNT(3 downto 2) & '0';
	else
		ADDR <= internal_COUNT(2 downto 0);
	end if;

	if(ECCgenCNTsel = '0') then
		ECCgenCNT <= internal_COUNT(8 downto 0);
	else
		ECCgenCNT <= "00000" & refCNT;
	end if;

	if(internal_COUNT >= x"833" and not(internal_COUNT = x"FFF")) then
		Done2100Bytes <= '1';
	else
		Done2100Bytes <= '0';
	end if;

end process CountUP;

SlowDOWNclk: process(clk, ResetTUGthelines, cntTUG)
	variable clkOUT : std_logic;
begin
	if(rising_edge(clk)) then
		if(ResetTUGthelines = '0') then
			cntTUG <= "000";
			clkOUT := '0';
		else
			cntTUG <= cntTUG + 1;
			if(cntTUG = "011") then
				clkOUT := '1';
			elsif(cntTUG = "101") then
				cntTUG <= "000";
				clkOUT := '0';
			end if;
		end if;
	end if;
	TUGthelines <= clkOUT;
	-- slowCLK <= clkOUT;
end process SlowDOWNclk;


SYNCfsmSYSTEM: process(clkDIVx3, Reset_L, cSTATE, nextSTATE, enableECCmodule)
begin
	if(rising_edge(clkDIVx3)) then
		if (Reset_L = '0') then
			cSTATE <= Start;
		else
			incrADDR_errLOC <= '0';
			triSTATEnandIO <= '1';
			case cSTATE is
				when Start =>
					triSTATEnandIO <= not(hostRE_L_tmp) or not(intRE_L)
							or(not(enableECCmodule) and not(hostRE_L));
				when ReadNAND =>
					triSTATEnandIO <= '0';
				when ReadNANDwaitforRB =>
					triSTATEnandIO <= '1';
				when ReadECCcalc =>
					triSTATEnandIO <= '1';
				when ReadECCfromNAND =>
					if(cntTUG = "011") then
						incrADDR_errLOC <= '1';
					else
						incrADDR_errLOC <= '0';
					end if;
					triSTATEnandIO <= '1';
				when ThrowINT =>
					triSTATEnandIO <= '1';
				when ProgramNAND =>
					triSTATEnandIO <= '0';
				when ProgramNANDaddr =>
					triSTATEnandIO <= '0';
				when ProgramNANDbufST2 =>
					triSTATEnandIO <= '0';
				when ProgramNANDeccCALC =>
					triSTATEnandIO <= '0';
				when ProgramNANDbufST0 =>
					triSTATEnandIO <= '0';
				when ProgramNANDfillinOther =>
					triSTATEnandIO <= '0';
				when ProgramNANDbufST1 =>
					triSTATEnandIO <= '0';
				when ProgramNANDeccwrite=>
					if(cntTUG = "011") then
						incrADDR_errLOC <= '1';
					else
						incrADDR_errLOC <= '0';
					end if;
					triSTATEnandIO <= '0';
				when ProgramNANDbufST3 =>
					triSTATEnandIO <= '0';
				when ProgramNANDcmd10h => -- this state writes the command
					triSTATEnandIO <= '0';
				when FetchERRORS =>
					triSTATEnandIO <= '1';
				when FetchERRORS_waitforRE =>
					triSTATEnandIO <= '1';
				when others =>
					triSTATEnandIO <= '1';
			end case;
			cSTATE <= nextSTATE;
		end if;
	end if;
end process SYNCfsmSYSTEM;

COMBfsmOUTPUTS: process(cSTATE, hostCLE_H_tmp, hostCE_L_tmp, hostWE_L_tmp, 
					hostIOin_tmp, hostRB_L_tmp, hostRE_L_tmp, 
					intRE_L, Done2100Bytes, TUGthelines, 
					NeedINT, intALE_H, intWE_L, cntTUG, hostALE_H_tmp, 
					internal_COUNT, intRB_L, intCE_L, intCLE_H, intWP_L,
					intIO, firstVAL, nandIO, HAMMING8bitin, ErrorLOCations,
					enableECCmodule, hostIOin, nandRB_L, hostCE_L,
					hostCLE_H, hostALE_H, hostWE_L, hostRE_L, hostWP_L)
	variable MUXselIO: std_logic := '0';
	variable fsmRB_L, fsmCE_L, fsmCLE_H, fsmALE_H, fsmWE_L,
			fsmRE_L, fsmWP_L :std_logic;
begin
	-- Variable outputs
	MUXselIO := '0'; --keep defaults
	-- FSM outputs
	fsmRB_L := '1';
	fsmCE_L := '1';
	fsmCLE_H := '0';
	fsmALE_H := '0';
	fsmWE_L := '1';
	fsmRE_L := '1';
	fsmWP_L := '1';

	interrINT_H <= '0';

	errlocADDRsel <= '0';
	-- WriteHAMMING to hostIO
	--whtHOSTio <= '0';
	--REstatus <= '0';
	--HAMMINGtoNANDsel <= '0';
 
	-- ECC state machine control
	ResetECCgen <= '1';
	SHOOTenable <= '1';
	ECCgenCNTsel <= '0';

	-- CounterCONTROL
	ResetCOUNTER_L <= '1';
	incCOUNT <= '0';

	-- MUX selects
	HammingINmuxSEL <= '0';
	
	-- TUG the lines
	ResetTUGthelines <= '0';
	--nandDriveBuffer <= hostDriveBuffer;
	STATEvec <= "1110";
	FFintIO <= '0';
	SELintIO10 <= '0';
	
	hostIOdrv <= '0';
	hostIOout <= x"BB";
	
	if(enableECCmodule = '0') then
		nandIOtempVAL <= hostIOin;
	else
		nandIOtempVAL <= intIO;
	end if;
	case cSTATE is
		when Start =>
			if(enableECCmodule = '0') then
				nandIOtempVAL <= hostIOin;
			else
				nandIOtempVAL <= intIO;
			end if;
			MUXselIO := '1';
			ResetCOUNTER_L <= '0';
			if (hostCLE_H_tmp = '1' and hostCE_L_tmp = '0' 
						and hostWE_L_tmp = '0' 
						and enableECCmodule = '1') then
				if(hostIOin_tmp = x"00") then
					nextSTATE <= ReadNAND;
				elsif(hostIOin_tmp = x"80") then
					nextSTATE <= ProgramNAND;
				elsif(hostIOin_tmp = ErrorFetchCommand) then
					nextSTATE <= FetchERRORS;
				end if;
			else
				nextSTATE <= Start;
			end if;
			STATEvec <= "0001";
			--STATEvec <= hostRB_L_tmp & "001";
			if(not(firstVAL) = '1' or not(intRE_L) = '1') then
				hostIOdrv <= '1';
				hostIOout <= nandIO;
			else
				hostIOdrv <= '0';
				hostIOout <= x"BB";
			end if;
-------------------- ERROR fetch States --------------------------
		when FetchERRORS =>
			errlocADDRsel <= '1';
			MUXselIO := '0';
			if(hostCLE_H_tmp = '0' and hostWE_L_tmp = '1') then
				nextSTATE <= FetchERRORS_waitforRE;

⌨️ 快捷键说明

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