OpenCores
URL https://opencores.org/ocsvn/z80control/z80control/trunk

Subversion Repositories z80control

[/] [z80control/] [trunk/] [CII_Starter_USB_API_v1/] [HW/] [Multi_Flash/] [Flash_Controller.v] - Rev 12

Compare with Previous | Blame | View Log

//Legal Notice: (C)2006 Altera Corporation. All rights reserved. Your
//use of Altera Corporation's design tools, logic functions and other
//software and tools, and its AMPP partner logic functions, and any
//output files any of the foregoing (including device programming or
//simulation files), and any associated documentation or information are
//expressly subject to the terms and conditions of the Altera Program
//License Subscription Agreement or other applicable license agreement,
//including, without limitation, that your use is for the sole purpose
//of programming logic devices manufactured by Altera and sold by Altera
//or its authorized distributors.  Please refer to the applicable
//agreement for further details.
 
module Flash_Controller(	//	Control Interface
							oDATA,iDATA,iADDR,iCMD,
							oReady,iStart,iCLK,iRST_n,
							//	Flash Interface
							FL_DQ,FL_ADDR,FL_WE_n,FL_CE_n,FL_OE_n,FL_RST_n);
 
/////////////	Control Interface	////////////////////////
input [21:0] iADDR;
input [7:0]	iDATA;
input [2:0] iCMD;
input iStart,iCLK,iRST_n;
output reg [7:0] oDATA;
output oReady;
/////////////	Flash Interface	////////////////////////
output reg [21:0] FL_ADDR;
inout [7:0] FL_DQ;
output FL_OE_n,FL_CE_n,FL_WE_n,FL_RST_n;
/////////////	Internal Register	////////////////////////
reg [21:0] Cont_Finish,CMD_Period;
reg [7:0] mDATA;
reg [10:0] Cont_DIV,WE_CLK_Delay,Start_Delay;
reg [3:0] ST;
reg mCLK,mStart,preStart,pre_mCLK,mACT;
reg mFinish;
reg [2:0] r_CMD;
reg [21:0] r_ADDR;
reg [7:0] r_DATA;
/////////////	Internal Wire	////////////////////////////
wire WE_CLK;
/////////////////////////////////////////////////////////
 
`include "Flash_Command.h"
 
/////////////	Flash Command Period	////////////////////
parameter PER_READ		=	1;			//	160		ns
parameter PER_WRITE 	= 	5;			//	800 	ns
parameter PER_BLK_ERA	= 	160000;		//	25.6	ms
parameter PER_SEC_ERA 	= 	160000;		//	25.6	ms
parameter PER_CHP_ERA	= 	640000;		//	102.4	ms		
parameter PER_ENTRY_ID	= 	4;			//	480		ns
parameter PER_RESET		= 	1;			//	160		ns
//////////////	 Flash State Machine	////////////////////
parameter IDEL		=	0;
parameter P1	 	= 	1;
parameter P2	 	= 	2;
parameter P3	 	= 	3;
parameter P4	 	=	4;
parameter P5	 	=	5;
parameter P3_PRG	= 	6;
parameter P3_DEV	= 	7;
parameter P4_PRG	=	8;
parameter P6_BLK_ERA=	9;
parameter P6_SEC_ERA=	10;
parameter P6_CHP_ERA=	11;
parameter READ		=	12;
parameter RESET		=	13;
////////////////	Clcok Setting	/////////////////////
//parameter CLK_Divide =	4;
parameter CLK_Divide =	8;
//parameter CLK_Divide =	16;
/////////////////////////////////////////////////////////
////	FL_OE_n  ?  Write =	1 : Read   = 0			/////
////	FL_CE_n  ?  IDEL  = 1 : ACTIVE = 0			/////
////	FL_RST_n ?  ON	  = 1 : RESET  = 0			/////
assign FL_DQ	= FL_OE_n ? mDATA : 8'bzzzzzzzz ;
assign FL_OE_n	= (ST == READ)	?	1'b0 : 1'b1 ;
assign FL_CE_n	= (ST == IDEL)	?	1'b1 : 1'b0 ;
assign FL_WE_n	= (ST == IDEL)	?	1'b1 :
				  (ST == READ)	?	1'b1 : WE_CLK;
assign FL_RST_n	= (ST == RESET) ?	1'b0 : 1'b1 ;
assign oReady	= mStart ?	1'b0 : mFinish;
/////////////////////////////////////////////////////////
//////////	 Flash State & WE Clock Generator	/////////
always@(posedge iCLK or negedge iRST_n)
begin
	if(!iRST_n)
	begin
		Cont_DIV		<=0;
		mCLK			<=0;
	end
	else
	begin
		Cont_DIV		<=Cont_DIV+1;
		mCLK			<=Cont_DIV[CLK_Divide>>2];
	end
end
////////////////////////////////////////////////////////
//////////////	  WE Clock Generator	////////////////
always@(posedge iCLK or negedge iRST_n)
begin
	if(!iRST_n)
	WE_CLK_Delay<=0;
	else
	WE_CLK_Delay<={WE_CLK_Delay[9:0],Cont_DIV[CLK_Divide>>2]};
end
assign	WE_CLK 	=	(CLK_Divide == 4)	?	~WE_CLK_Delay[3]	:
					(CLK_Divide == 8)	?	~WE_CLK_Delay[4]	:
											~WE_CLK_Delay[10]	;
////////////////////////////////////////////////////////
///////////	 Input Signal & Data Latch	////////////////
always@(posedge iCLK or negedge iRST_n)
begin
	if(!iRST_n)
	begin
		mStart			<=0;
		Start_Delay		<=0;
		preStart		<=0;
		pre_mCLK		<=0;
		mACT			<=0;
	end
	else
	begin
		////////	State Active Detect	//////////
		if({pre_mCLK,mCLK}==2'b01)
		mACT<=1;
		else
		mACT<=0;
		pre_mCLK<=mCLK;
		//////////////////////////////////////////
		//////	Input Signal & Data Latch	//////
		if({preStart,iStart}==2'b01)
		begin
			mStart		<=1'b1;
			Start_Delay	<=8'h00;
			r_CMD<=iCMD;
			r_ADDR<=iADDR;
			r_DATA<=iDATA;
		end
		else
		begin
			if(Start_Delay<CLK_Divide)
			Start_Delay<=Start_Delay+1;
			else
			mStart<=1'b0;
		end
		preStart<=iStart;
		//////////////////////////////////////////
	end
end
////////////////////////////////////////////////////////
/////////////	Flash Output Latch	////////////////////
always@(posedge iCLK or negedge iRST_n)
begin
	if(!iRST_n)
	oDATA<=0;
	else
		if( mACT && (ST==READ))
		oDATA<=FL_DQ;
end
////////////////////////////////////////////////////////
//////////////	 Flash State Control	////////////////
always@(posedge iCLK or negedge iRST_n)
begin
	if(!iRST_n)
	ST<=IDEL;
	else
	begin
		if(mACT)	//	State Active Flag
		begin
			if(mStart)
			begin
				case(r_CMD)
				CMD_READ	:	ST<=READ;
				CMD_WRITE	:	ST<=P1;
				CMD_BLK_ERA	:	ST<=P1;
				CMD_SEC_ERA	:	ST<=P1;
				CMD_CHP_ERA	:	ST<=P1;
				CMD_ENTRY_ID:	ST<=P1;
				CMD_RESET	:	ST<=RESET;
				endcase
			end
			else
			begin
				case(ST)
				IDEL:		ST <= IDEL;
				P1:			ST <= P2;
				P2:			begin
								case(r_CMD)
								CMD_WRITE	:	ST <= P3_PRG;
								CMD_ENTRY_ID:	ST <= P3_DEV;
								default		:	ST <= P3;
								endcase
							end
				P3:			ST <= P4;
				P4:			ST <= P5;
				P5:			begin
								case(r_CMD)
								CMD_BLK_ERA	:	ST <= P6_BLK_ERA;
								CMD_SEC_ERA	:	ST <= P6_SEC_ERA;
								CMD_CHP_ERA	:	ST <= P6_CHP_ERA;
								endcase
							end
				P3_PRG:		ST <= P4_PRG;
				P3_DEV:		ST <= IDEL;
				P4_PRG:		ST <= IDEL;
				P6_BLK_ERA:	ST <= IDEL;
				P6_SEC_ERA:	ST <= IDEL;
				P6_CHP_ERA:	ST <= IDEL;
				READ:		ST <= IDEL;
				RESET:		ST <= IDEL;
				endcase
			end
		end
	end
end
////////////////////////////////////////////////////////
//////////////	 Output Finish Control	////////////////
always@(posedge iCLK or negedge iRST_n)
begin
	if(!iRST_n)
	begin
		mFinish<=0;
		Cont_Finish<=0;
	end
	else
	begin
		if(mACT)	//	State Active Flag
		begin
			if(mStart)
			begin
				mFinish		<=1'b0;
				Cont_Finish	<=0;
			end
			else
			begin
				if(Cont_Finish < CMD_Period)
				Cont_Finish	<=	Cont_Finish+1;
				else
				mFinish		<=	1'b1;
			end
		end
	end
end
////////////////////////////////////////////////////////	
//////////////	 Command Period LUT	////////////////////
always@(posedge iCLK)
begin
	case(r_CMD)
	CMD_READ	:	CMD_Period	<=	PER_READ-1;
	CMD_WRITE	:	CMD_Period	<=	PER_WRITE-1;
	CMD_BLK_ERA	:	CMD_Period	<=	PER_BLK_ERA-1;
	CMD_SEC_ERA	:	CMD_Period	<=	PER_SEC_ERA-1;
	CMD_CHP_ERA	:	CMD_Period	<=	PER_CHP_ERA-1;
	CMD_ENTRY_ID:	CMD_Period	<=	PER_ENTRY_ID-1;
	CMD_RESET	:	CMD_Period	<=	PER_RESET-1;
	endcase
end
////////////////////////////////////////////////////////
////////////////	Command State LUT	////////////////
always
begin
	case(ST)
	IDEL:	begin
				FL_ADDR <= 22'h000000;	mDATA 	<= 8'h00;
			end
	P1:		begin
				FL_ADDR <= 22'h000AAA; 	mDATA 	<= 8'hAA;			
			end										
	P2:		begin
				FL_ADDR <= 22'h000555;	mDATA 	<= 8'h55;						
			end	
	P3:		begin
				FL_ADDR <= 22'h000AAA;	mDATA 	<= 8'h80;						 
      		end
	P4:		begin
				FL_ADDR <= 22'h000AAA;	mDATA 	<= 8'hAA;						 
      		end
	P5:		begin
				FL_ADDR <= 22'h000555;	mDATA 	<= 8'h55;						 
     	 	end
	P3_PRG:	begin
				FL_ADDR <= 22'h000AAA;	mDATA 	<= 8'hA0;						 
      		end
	P3_DEV:	begin
				FL_ADDR <= 22'h000AAA;	mDATA 	<= 8'h90;						 
      		end
	P4_PRG:	begin
				FL_ADDR <= r_ADDR;		mDATA 	<= r_DATA;					 
      		end
	P6_BLK_ERA:	
			begin
				FL_ADDR <= r_ADDR<<12;	mDATA 	<= 8'h30;					 
      		end
	P6_SEC_ERA:	
			begin
				FL_ADDR <= r_ADDR<<16;	mDATA 	<= 8'h50;					 
      		end
	P6_CHP_ERA:	
			begin
				FL_ADDR <= 22'h000AAA;	mDATA 	<= 8'h10;					 
      		end
	READ:	begin
				FL_ADDR <= r_ADDR;		mDATA 	<= 8'h00;
			end
	RESET: begin
				FL_ADDR <= 22'h000000;	mDATA 	<= 8'h00;
			end
	endcase
end
////////////////////////////////////////////////////////
 
endmodule

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.