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

📄 st2fsm.vhd

📁 NAND Flash Controller & ECC VHDL Code
💻 VHD
📖 第 1 页 / 共 3 页
字号:
		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 <= STeraseblock;
		end if;

	when STeraseblockADDcycles =>
		outputVEC1 <= "10100";
		outputVEC2 <= "11100";
		nandDATA_fsm <= '1';
		enableTOGGLE <= '1';
		if (doneTOGGLE = '1') then
			Nstate <= enableTOG0;
		else
			Nstate <= STeraseblockADDcycles;
		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 STeraseblockCMDd0 =>
		internal_nandDATA <= x"D0";
		outputVEC1 <= "10010";
		outputVEC2 <= "11010"; 
		nandDATA_fsm <= '1';
		enableTOGGLE <= '1';
		if (doneTOGGLE = '1') then
			Nstate <= STwaitforRB0;
		else 
			Nstate <= STeraseblockCMDd0;
		end if; 			 		

	-- Reset Nand state 		
	when STresetNAND =>
		internal_nandDATA <= x"FF";
		outputVEC1 <= "10010";
		outputVEC2 <= "11010";
		nandDATA_fsm <= '1';
		enableTOGGLE <= '1';
		if (doneTOGGLE = '1') then 
			Nstate <= STwaitforRB0;
		else
			Nstate <= STresetNAND;
		end if; 

	-- Fetch Error states
	when STfetchERRORs =>
		internal_nandDATA <= ErrorFetchCommand;
		outputVEC1 <= "10010";
		outputVEC2 <= "11010";
		nandDATA_fsm <= '1';
		enableTOGGLE <= '1';
		if (doneTOGGLE = '1') then
			Nstate <= enableTOG0;
		else
			Nstate <= STfetchERRORs;
		end if;
		DEBUGstatevector <= x"20";
 		
	when STfetchERRORseightReads =>
		-- bit 0 - CE_L 
		-- bit 1 - CLE_H
		-- bit 2 - ALE_H
		-- bit 3 - WE_L
		-- bit 4 - RE_L
		outputVEC1 <= "01000";
		outputVEC2 <= "11000";
		nandDATA_fsm <= '0';
		enableTOGGLE <= '1';
		if (doneTOGGLE = '1') then
			Nstate <= enableTOG0;
		else 
			Nstate <= STfetchERRORseightReads;
		end if;
			DEBUGstatevector <= x"21";

	-- Read ID states
	when STreadID =>
		internal_nandDATA <= x"90";
		outputVEC1 <= "10010";
		outputVEC2 <= "11010";
		nandDATA_fsm <= '1';
		enableTOGGLE <= '1';
		if (doneTOGGLE = '1') then
			Nstate <= enableTOG0;
		else
			Nstate <= STreadID;
		end if;
		
	when STreadIDadd00 =>
		internal_nandDATA <= x"00";
		outputVEC1 <= "10100";
		outputVEC2 <= "11100";
		nandDATA_fsm <= '1';
		enableTOGGLE <= '1';
		if (doneTOGGLE = '1') then
			Nstate <= enableTOG0;
		else
			Nstate <= STreadIDadd00;
		end if;

	when STreadIDfourReads =>
		-- bit 0 - CE_L
		-- bit 1 - CLE_H
		-- bit 2 - ALE_H
		-- bit 3 - WE_L
		-- bit 4 - RE_L
		outputVEC1 <= "01000";
		outputVEC2 <= "11000";
		nandDATA_fsm <= '0';
		enableTOGGLE <= '1';
		if (doneTOGGLE = '1') then
			Nstate <= enableTOG0;
		else
			Nstate <= STreadIDfourReads;
		end if;

	-- Status read states
	when STreadstatusCMD =>
		internal_nandDATA <= x"70";
		outputVEC1 <= "10010";
		outputVEC2 <= "11010";
		nandDATA_fsm <= '1';
		enableTOGGLE <= '1';
		if (doneTOGGLE = '1') then
			Nstate <= enableTOG0;
		else 
			Nstate <= STreadstatusCMD;
		end if;
	
	when STreadstatusRead =>
		nandDATA_fsm <= '0';
		outputVEC1 <= "01000";
		outputVEC2 <= "11000";
		enableTOGGLE <= '1';
		if (doneTOGGLE = '1') then
			Nstate <= Start;
		else
			Nstate <= STreadstatusRead;
		end if; 	
	end case; 
end process;  

toggleFSM: process (clk, Reset_L) 

begin 	
	if(rising_edge(clk)) then
		if(rstDcnt_L = '0') then
			delayCNT <= "000";
		else
			if(delayCNT = "101") then
				delayCNT <= "000";
			elsif(incDcnt = '1') then
				delayCNT <= delayCNT + 1;
			end if;
		end if;
	if(Reset_L = '0') then
		cTOGstate <= toggleWAIT;

	-- NAND or NAND ecc module interface
	--nandCE_L <= '1';
	--nandCLE_H <= '0';
	--nandALE_H <= '0';
	--nandWE_L <= '1';
	--nandRE_L <= '1'; 		
	else
		-- nand DATA bus MUX 			
		if(nandDATA_from_buffer1 = '1') then
			nandDATA <= buffer1_DATAout;
		elsif(nandDATA_from_buffer2 = '1') then
			nandDATA <= buffer2_DATAout;
		elsif(nandDATA_fsm = '1') then 
			nandDATA <= internal_nandDATA;
		else 
			nandDATA <= (others => 'Z');
		end if; 			
		case cTOGstate is
			when toggleWAIT =>
				nandCE_L <= outputVEC1(0);
				nandCLE_H <= outputVEC1(1);
				nandALE_H <= outputVEC1(2);
				nandWE_L <= outputVEC1(3);
				nandRE_L <= outputVEC1(4);
			when toggle1 =>
				nandCE_L <= outputVEC1(0);
				nandCLE_H <= outputVEC1(1);
				nandALE_H <= outputVEC1(2);
				nandWE_L <= outputVEC1(3);
				nandRE_L <= outputVEC1(4);
			when toggle2 =>
				nandCE_L <= outputVEC2(0);
				nandCLE_H <= outputVEC2(1);
				nandALE_H <= outputVEC2(2);
				nandWE_L <= outputVEC2(3);	
				nandRE_L <= outputVEC2(4);
			when toggleDONE =>
				nandCE_L <= '1';
				nandCLE_H <= '0';
				nandALE_H <= '0';
				nandWE_L <= '1'; 
				nandRE_L <= '1';
		end case;
		cTOGstate <= nTOGstate;
	end if; 
	end if; 
end process toggleFSM;  

COMBtoggleFSM: process(cTOGstate, enableTOGGLE, delayCNT, internalCNT, CNTupto, outputVEC1, outputVEC2) 

begin 	
	doneTOGGLE <= '0';
	internalCNTRst_L <= '1';
	incintCNT <= '0';
	rstDcnt_L <= '1';
	incDcnt <= '0'; 
	case cTOGstate is 
		when toggleWAIT =>
			rstDcnt_L <= '0';
			if(enableTOGGLE = '1') then
				nTOGstate <= toggle1;
			else
				nTOGstate <= toggleWAIT;
			end if;
			internalCNTRst_L <= '0';

		when toggle1 =>
			incDcnt <= '1';
			-- this is swtiching at 2 as
			-- first it takes a clock cycle to switch 
			-- states and then it takes another clock to switch the register 			
			if(delayCNT >= "011") then
				nTOGstate <= toggle2;
			else
				nTOGstate <= toggle1;
			end if;
	
		when toggle2 =>
			incDcnt <= '1';
			if (delayCNT = "100") then 
				incintCNT <= '1'; 			
			end if;
			-- switching at 4 as the same reason
			-- 2 clocks before the signal goes back 			
			if (delayCNT >= "101") then
				if(internalCNT >= CNTupto) then
	 				nTOGstate <= toggleDONE;
				else
					nTOGstate <= toggle1;
				end if;
			else
				nTOGstate <= toggle2;
			end if;

		when toggleDONE =>
			rstDcnt_L <= '0';
			doneTOGGLE <= '1';
			if (enableTOGGLE = '0') then
				nTOGstate <= toggleWAIT;
			else
				nTOGstate <= toggleDONE;
			end if; 
		end case; 
	end process COMBtoggleFSM;
  
REPETITIONcounter: process(clk, internalCNTRst_L, incintCNT) 

begin
	if(rising_edge(clk)) then
		if(internalCNTRst_L = '0') then
			internalCNT <= x"000";
		else
			if (incintCNT = '1') then
				internalCNT <= internalCNT + 1;
			end if;
		end if;
	end if; 
end process REPETITIONcounter;   

MUXoutsignals: process(buffer1_nandDATA_in, buffer2_nandDATA_in, nandDATA_from_buffer1, nandDATA_from_buffer2, 
			nandDATA, ST2inDATA, buffer1_DATAout, buffer2_DATAout, nandDATA_fsm, internal_nandDATA, buffer1or2, 
			ADDR, internalCNTaddr, nandID, ECCpresent, Device_Size, Device8_not16, StatusREG, CommandREG, OE_L, 
			CE_L, WE_L, currentADDreg, errorLOC, errCORaddrIN, corINPUTdata, corADDR) 

begin  	
	-- Buffer 1 and 2: data inputs
	if(buffer1_nandDATA_in = '1') then
		if(errCORaddrIN = '1') then
			buffer1_DATA <= corINPUTdata;
		else
			buffer1_DATA <= nandDATA;
		end if; 	
	else
		buffer1_DATA <= ST2inDATA;
	end if;
	if(buffer2_nandDATA_in = '1') then
		if(errCORaddrIN = '1') then
			buffer2_DATA <= corINPUTdata;
		else
			buffer2_DATA <= nandDATA;
		end if; 	
	else
		buffer2_DATA <= ST2inDATA;
	end if;  	

	-- buffer addressing
	if(buffer1or2 = '0') then
		if(ADDR < x"840") then
			buffer1_ADDR <= ADDR;
		else
			buffer1_ADDR <= x"840";
		end if;
	if(errCORaddrIN = '1') then
			buffer2_ADDR <= corADDR;
		else
			buffer2_ADDR <= internalCNTaddr;
		end if; 	
	else
		if(ADDR < x"840") then
			buffer2_ADDR <= ADDR;
		else
			buffer2_ADDR <= x"840";
		end if;
	if(errCORaddrIN = '1') then
			buffer1_ADDR <= corADDR;
		else
			buffer1_ADDR <= internalCNTaddr;
		end if; 	
	end if;
	if(OE_L='0' and CE_L = '0' and WE_L = '1') then
		if(ADDR(11 downto 4) = x"FF") then
			if(ADDR(3 downto 0) = x"0") then
				ST2outDATA <= nandID(0);
			elsif(ADDR(3 downto 0) = x"1") then
				ST2outDATA <= nandID(1);
			elsif(ADDR(3 downto 0) = x"2") then
				ST2outDATA <= nandID(2);
			elsif(ADDR(3 downto 0) = x"3") then
				ST2outDATA <= nandID(3);
			elsif(ADDR(3 downto 0) = x"4") then
				ST2outDATA <= REGaddress(conv_integer(currentADDreg))(0);
			elsif(ADDR(3 downto 0) = x"5") then
				ST2outDATA <= REGaddress(conv_integer(currentADDreg))(1);
			elsif(ADDR(3 downto 0) = x"6") then
				ST2outDATA <= REGaddress(conv_integer(currentADDreg))(2);
			elsif(ADDR(3 downto 0) = x"7") then 
				ST2outDATA <= '0' & ECCpresent & "000" & Device_Size & Device8_not16;
			elsif(ADDR(3 downto 0) = x"8") then
				ST2outDATA <= "000000" & currentADDreg & buffer1or2;
			elsif(ADDR(3 downto 0) = x"9") then
				ST2outDATA <= StatusREG;
			elsif(ADDR(3 downto 0) = x"A") then
				ST2outDATA <= CommandREG;
			else 
			--ST2outDATA <= (others => 'Z');
			ST2outDATA <= x"AA";
			end if; 		
	elsif(ADDR(11 downto 3) = x"FE" & '0') then
		ST2outDATA <= errorLOC(conv_integer(ADDR(2 downto 0))); 
	else
		if(buffer1or2 = '0') then
			ST2outDATA <= buffer1_DATAout;
		else
			ST2outDATA <= buffer2_DATAout;
		end if;
	end if; 	
	else
	ST2outDATA <= x"AA";
	--DATA <= (others => 'Z');
	end if; 
end process MUXoutsignals;  
end syn;
---------------------------------------------------
-- 		 FSM Ends
---------------------------------------------------

⌨️ 快捷键说明

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