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

📄 st2fsm.vhd

📁 NAND Flash Controller & ECC VHDL Code
💻 VHD
📖 第 1 页 / 共 3 页
字号:
		NEXTtonextST <= NEXTtonextST2;

	-- Read ID cycles
	when STreadID =>
		--internal_nandDATA <= x"90";
		cntUPTO <= x"000";
		NEXTtonextST <= STreadIDadd00;
	when STreadIDadd00 =>
		--internal_nandDATA <= x"00";
		NEXTtonextST <= STreadIDfourReads;
		cntUPTO <= x"000";
	when STreadIDfourReads =>
		if(incintCNT = '1') then
			nandID(conv_integer(internalCNT(1 downto 0))) <= nandDATA;
		end if; 					
		cntUPTO <= x"004";
		NEXTtonextST <= Start; 			

	-- Read Status cycles
	when STreadstatusCMD =>
		cntUPTO <= x"000";
		NEXTtonextST <= STreadstatusRead;
		--internal_nandDATA <= x"70";
	when STreadstatusRead =>
		if(incintCNT = '1') then
			StatusREG <= nandDATA;
		end if;
		cntUPTO <= x"000";
	when others =>
		end case; 			
		Cstate <= Nstate; 		
		end if; 	
	end if;  
	end process statemachine;   

	-- FallingEDGE 
	-- This process is to generate the latch signal on 
	-- RE going high. 
	FallingEDGE: process(clk, Reset_L) 
	begin 	
		if(falling_edge(clk)) then
			if (Reset_L='0') then 
				OnedelayedINCcnt <= '0';
			else
				OnedelayedINCcnt <= incintCNT;
			end if; 	
		end if; 
	end process FallingEDGE;   
	combFSMmain: process(cState, ADDR, we_L, ST2inDATA, doneTOGGLE, NEXTtonextST, incintCNT, CE_L, buffer1or2, OE_L, 
				internalCNT, nandRB_Lfinal, OnedelayedINCcnt, buffer1_DATAout, buffer2_DATAout, delayCNT,
				nandRB_L, errINT, corWE, errorLOC) 
	
begin 	
	-- STANDARD SRAM interface      
	INT <= '0';
	RB_L <= '0';
	nandWP_L <= '1'; 
	
	-- BUFFER 1 and 2 WE signals 	
	WE_buffer1_H <= not(buffer1or2) and not(WE_L) and not(CE_L);
	WE_buffer2_H <= buffer1or2 and not(WE_L) and not(CE_L);
	
	-- Internal signals 	
	buffer1_nandDATA_in <= '0';
	buffer2_nandDATA_in <= '0';
	nandDATA_from_buffer1 <= '0';
	nandDATA_from_buffer2 <= '0';   	
	
	-- Toggle state machine stuff
	enableTOGGLE <= '0';
	nandDATA_fsm <= '0';
	outputVEC1 <= "11001";
	outputVEC2 <= "11001";
	flipTHEt <= '0'; 
	Nstate <= Start;  	
	internal_nandDATA <= x"00";
	errCORaddrIN <= '0';
	corADDR <= x"000";
	corWE <= '0';
  	DEBUGstatevector <= x"0A";
	case cSTATE is 		
		when Start =>
			if(ADDR = x"FFA" and WE_L = '0' and CE_L = '0') then
				if(ST2inDATA(7 downto 4) = x"7") then  
					-- Status read
					Nstate <= STreadstatusCMD;
				elsif(ST2inDATA(7 downto 4) = x"9") then  
					-- Read ID
					Nstate <= STreadID;
				elsif(ST2inDATA(7 downto 4) = x"6") then  
					-- Erase Block
					Nstate <= STeraseblock;
				elsif(ST2inDATA(7 downto 4) = x"F") then  
					-- Reset NAND flash
					Nstate <= STresetNAND;
				elsif(ST2inDATA(7 downto 4) = x"8") then  
					-- Program Page
					Nstate <= STprogrampageCHbuf;
				elsif(ST2inDATA(7 downto 4) = x"0") then  
					-- Read Page
					Nstate <= STreadpage;
				elsif(ST2inDATA(7 downto 0) = x"23") then  
					-- Fetch Errors
					Nstate <= STfetchERRORS;
				else 					
					Nstate <= Start;
			end if; 			
		else 				
			Nstate <= Start;
		end if;
		RB_L <= '1';
		DEBUGstatevector <= x"11";

		-- The common done toggle state
		when enableTOG0 =>
			nandDATA_fsm <= '0';
			enableTOGGLE <= '0';
			outputVEC1 <= "11001";
			outputVEC2 <= "11001";
			if (doneTOGGLE = '0') then
				Nstate <= NEXTtonextST;
			else
				Nstate <= enableTOG0;
			end if; 		  	
			DEBUGstatevector <= x"12";

		when STwaitforRB0 =>
			internal_nandDATA <= x"00"; 			
			outputVEC1 <= "11001";
			outputVEC2 <= "11001";
			nandDATA_fsm <= '0';
			enableTOGGLE <= '0';
			if (nandRB_Lfinal = '0') then
				Nstate <= STwaitforRB1;
			else
				Nstate <= STwaitforRB0;
			end if;
			DEBUGstatevector <= x"13";

		when STwaitforRB1 =>
			internal_nandDATA <= x"00";
			outputVEC1 <= "11001";
			outputVEC2 <= "11001";
			nandDATA_fsm <= '0';
			enableTOGGLE <= '0';
			if (nandRB_Lfinal = '1') then
				Nstate <= NEXTtonextST;
			else 				
				Nstate <= STwaitforRB1;
			end if; 		

		-- Program cycles
		when STprogrampageCHbuf =>
			flipTHEt <= '1';
			internal_nandDATA <= x"00";
			outputVEC1 <= "10010";
			outputVEC2 <= "11010";
			nandDATA_fsm <= '0';
			enableTOGGLE <= '0';
			Nstate <= STprogrampage;

		when STprogrampage =>
			internal_nandDATA <= x"80";
			outputVEC1 <= "10010";
			outputVEC2 <= "11010";
			nandDATA_fsm <= '1';
			enableTOGGLE <= '1';
			if (doneTOGGLE = '1') then
				Nstate <= enableTOG0;
			else
				Nstate <= STprogrampage;
			end if; 		

		when STprogrampageADDlatch00 =>
			internal_nandDATA <= x"00";
			outputVEC1 <= "10100";
			outputVEC2 <= "11100";
			nandDATA_fsm <= '1';
			enableTOGGLE <= '1';
			if (doneTOGGLE = '1') then
				Nstate <= enableTOG0;
			else 
				Nstate <= STprogrampageADDlatch00;
			end if; 		
		
		when STprogrampageADDlatch3cycles =>
			outputVEC1 <= "10100";
			outputVEC2 <= "11100";
			nandDATA_fsm <= '1';
			enableTOGGLE <= '1';
			if (doneTOGGLE = '1') then
				Nstate <= enableTOG0;
			else 
				Nstate <= STprogrampageADDlatch3cycles;
			end if;
			if(internalCNT(1 downto 0) = "11") then
				internal_nandDATA <= x"00";
			else
				internal_nandDATA <= 
				REGaddress(conv_integer(not(currentADDreg)))(conv_integer(internalCNT(1 downto 0)));
 			end if;
  		
		when STprogrampageWRITES => 			
			outputVEC1 <= "10000";
			outputVEC2 <= "11000";
			nandDATA_fsm <= '0';
			enableTOGGLE <= '1';
			if (doneTOGGLE = '1') then
				Nstate <= enableTOG0;
			else
				Nstate <= STprogrampageWRITES;
			end if;
			if(buffer1or2 = '0') then
				-- This means the user has buffer 1
				-- So use buffer 2 as the buffers have been
				-- swapped 				
				internal_nandDATA <= buffer2_DATAout;
				nandDATA_from_buffer2 <= '1'; 			
				else 				
					internal_nandDATA <= buffer1_DATAout;
					nandDATA_from_buffer1 <= '1'; 			
				end if; 		

		when STprogrampageCMDfinal10h =>
			internal_nandDATA <= x"10";
			outputVEC1 <= "10010";
			outputVEC2 <= "11010";
			nandDATA_fsm <= '1';
			enableTOGGLE <= '1';
			if (doneTOGGLE = '1') then
				Nstate <= STwaitforRB0;
			else 
				Nstate <= STprogrampageCMDfinal10h;
			end if; 		

		when STprogrampageSWstatusRB =>
			Nstate <= Start;
		
		-- Read Cycles
		when STreadpage =>
			internal_nandDATA <= x"00";
			outputVEC1 <= "10010";
			outputVEC2 <= "11010";
			nandDATA_fsm <= '1';
			flipTHEt <= not(delayCNT(0) or delayCNT(1) or delayCNT(2));
			enableTOGGLE <= '1';
			if (doneTOGGLE = '1') then
				Nstate <= enableTOG0;
			else
				Nstate <= STreadpage;
			end if;
		
		when STreadpageADDlatch00 =>
			internal_nandDATA <= x"00";
			outputVEC1 <= "10100";
			outputVEC2 <= "11100";
			nandDATA_fsm <= '1';
			enableTOGGLE <= '1';
			if (doneTOGGLE = '1') then
				Nstate <= enableTOG0;
			else
				Nstate <= STreadpageADDlatch00;
			end if; 		

		when STreadpageADDlatch3cycles =>
			outputVEC1 <= "10100";
			outputVEC2 <= "11100";
			nandDATA_fsm <= '1';
			enableTOGGLE <= '1';
			if (doneTOGGLE = '1') then
				Nstate <= enableTOG0;
			else 
				Nstate <= STreadpageADDlatch3cycles;
			end if;
			-- set the Register address on the lines
			if(internalCNT(1 downto 0) = "11") then
				internal_nandDATA <= x"00";
			else
				internal_nandDATA <= 
				REGaddress(conv_integer(not(currentADDreg)))(conv_integer(internalCNT(1 downto 0)));
 			end if; 		

		when STreadpageCMDfinal30h =>
			internal_nandDATA <= x"30";
			outputVEC1 <= "10010";
			outputVEC2 <= "11010";
			nandDATA_fsm <= '1';
			enableTOGGLE <= '1';
			if (doneTOGGLE = '1') then
				Nstate <= STwaitforRB0;
			else 
				Nstate <= STreadpageCMDfinal30h;
			end if;
	
		when STreadpageREADS =>
			internal_nandDATA <= x"00";
			outputVEC1 <= "01000";
			outputVEC2 <= "11000";
			nandDATA_fsm <= '0';
			enableTOGGLE <= '1';
			if (doneTOGGLE = '1') then
				Nstate <= STreadpageCORwaitforRB;
			else
				Nstate <= STreadpageREADS;
			end if;
			if(buffer1or2 = '0') then
				-- This means the user has buffer 1
				-- to keep the default we do this:-
				WE_buffer1_H <= not(WE_L) and not(CE_L);
				-- to write to the other buffer
				WE_buffer2_H <= OneDelayedINCcnt;
				buffer2_nandDATA_in <= '1';
			else
				WE_buffer1_H <= OneDelayedINCcnt;
				-- to keep the default
				WE_buffer2_H <= not(WE_L) and not(CE_L);
				buffer1_nandDATA_in <= '1';
			end if;
		  	DEBUGstatevector <= x"BB";
		
		when STreadpageCORwaitforRB =>
			if(nandRB_L = '0') then
				Nstate <= STreadpageCORRECT;
			elsif(ECCpresent = '0') then
				Nstate <= STreadpageSWAPbuf;
			else
				Nstate <= STreadpageCORwaitforRB;
			end if;
		  	DEBUGstatevector <= x"CC";
		
		when STreadpageCORRECT =>
			if(nandRB_L = '1') then
				if(errINT = '1') then
					Nstate <= STfetchERRORs;
				else
					Nstate <= STreadpageSWAPbuf;
				end if;
			else
				Nstate <= STreadpageCORRECT;
			end if;
		  	DEBUGstatevector <= x"CE";
		
		when STreadpageCORRECTaddr =>
			errCORaddrIN <= '1';	
			if(buffer1or2 = '0') then 				
				-- This means the user has buffer 1
				-- to keep the default we do this:-
				WE_buffer1_H <= not(WE_L) and not(CE_L);
				-- to write to the other buffer
				WE_buffer2_H <= corWE;
				buffer2_nandDATA_in <= '1';
			else
				WE_buffer1_H <= corWE;
				-- to keep the default
				WE_buffer2_H <= not(WE_L) and not(CE_L);
				buffer1_nandDATA_in <= '1';
			end if;
			if(delayCNT = "011") then
				corWE <= errorLOC(conv_integer(internalCNT(1 downto 0) & '1'))(4) and
					not(errorLOC(conv_integer(internalCNT(1 downto 0) & '1'))(5));
			else
				corWE <= '0';
			end if;
			corADDR <= '0' & internalCNT(1 downto 0) & 
					errorLOC(conv_integer(internalCNT(1 downto 0) & '1'))(3 downto 0)
					& errorLOC(conv_integer(internalCNT(1 downto 0) & '0'))(7 downto 3); 			
			enableTOGGLE <= '1';
			if (doneTOGGLE = '1') then
				Nstate <= STreadpageSWAPbuf;
			else
				Nstate <= STreadpageCORRECTaddr;
			end if;
			DEBUGstatevector <= x"CF";
		
	when STreadpageSWAPbuf =>
			DEBUGstatevector <= x"DD";
			Nstate <= Start; 		

	-- Erase Block states
		when STeraseblock =>
		internal_nandDATA <= x"60";
		outputVEC1 <= "10010";

⌨️ 快捷键说明

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