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

📄 flash_interface08.v

📁 flash interface controller, verilog coding
💻 V
字号:
`timescale 1ns/1nsmodule Flash_InterFace(CLK,RST_N,CE_h,OE_h,WE_h,SecEr,Adr_h,DataIn_h,DataOut_h,DataValid_N,DataIdle_N,											 CE_s,OE_s,WE_s,Adr_s,Data_s);	input CLK;                   //System Clock;系统时钟信号;	input RST_N;                 //System Reset, active when it is low;系统复位清零信号,低电平有效;	input CE_h;                  //Host Chip Select, active when it is low; 主端片选信号,低电平有效;	input OE_h;                  //Host Output Control,主端输出控制信号,高电平写,低电平读;	input WE_h;                  //Host Write Control, 主端操作控制信号,低电平有效,启动读/写;	input SecEr;                 //Host Sector Erase, active when it is High,主端输入Sector Erase信号,高电平有效;	input [20:0]Adr_h;           //Host Address, 主端地址信号,21bits;	input [31:0]DataIn_h;        //Host Input Data, 主端方输入数据线;	output [31:0]DataOut_h;      //Host Output Data,主端方输出数据线;	output DataValid_N;          //Data Valid Signal, Active when it is low;数据有效信号,低电平有效;	output DataIdle_N;           //Data Idle Signal, active when it is low;数据空闲信号,第电平有效;		output CE_s;                 //Slave Chip Select,active when it is low;从端片选信号,低电平有效;	output OE_s;                 //Slave Output Control,从端输出控制信号,高电平写,低电平读;	output WE_s;                 //Slave Write Control,从端操作控制信号,低电平有效,启动读/写操作;	output [20:0]Adr_s;          //Slave Address,从端地址信号,21bits;		inout [15:0]Data_s;          //inout port of the Slave Part on the Flash;直接连接到Flash上;		parameter Delay_Read=4'b1010;        // Delay at least 90ns;	parameter Delay_WE_P=4'b0110;        //Delay of the WE Pulse,Mix Time is 40ns;	parameter Delay_WE_PH=4'b0100;       //Delay of the WE Pulse High, Mix Time is 30ns;	parameter Delay_1us=8'b01100100;     //Delay of 1us of the polling time;			wire CLK,RST_N,CE_h,OE_h,WE_h,SecEr;	wire [20:0]Adr_h;	wire [31:0]DataIn_h;		reg DataValid_N;	reg DataIdle_N;	reg CE_s;	reg OE_s;	reg WE_s;	reg [20:0]Adr_s;	reg [31:0]DataOut_h;	reg DQ7_Temp;              //Temp Data of the DQ7 for the DataPolling; DataPolling中的DQ7的临时贮存;	reg [15:0] Data_temp;       //Temp Data for the Slave;从端数据临时存储;	reg [20:0] Adr_temp;             //临时地址		reg [3:0]CountRead;          //CLK Counts for the Delay of Read Operation;读延时时钟周期计数;	reg [3:0]CountStep;          //CLK Counts for the Delay of the Steps;Load Steps延时时钟周期计数;	reg [3:0]CountWE;            //WE Counts,WE变化计数;	reg [7:0] Count_1us;         //ius Counts,1us计数;		wire FlashRead_N;             //Flash Word Read Time Control;Flash读延时控制,当信号为低时,已经从Flash中读出了一个Word;	reg ReadCtrl;                //Read Data Control Signal;读操作地址变换控制信号	reg Busy;                    //Busy Signal in the Internal Program of the Write Operation;高电平未完成,Programming;		//Read Delay CLK Counter;读延时时钟周期计数器;	assign FlashRead_N=|CountRead;       //这样写综合好吗?还是直接用AND门处理?		always @(posedge CLK or negedge RST_N)		begin			if (RST_N == 0)				begin					ReadCtrl<=0;					CountRead<=4'b0000;				end			else if((OE_h==0)&&(CE_h==0)&&(WE_h==0))  //Read Operation permitted;				begin					ReadCtrl<=ReadCtrl+&(~CountRead);					if (CountRead<Delay_Read)						CountRead<=CountRead+1;					else						CountRead<=4'b0000;				end		end				//Step Sequence Delay Counts;	always @(posedge CLK or negedge RST_N)		begin			if (RST_N == 0)				CountStep<=4'b0000;			else if ((CE_s==0)&&(OE_s==1))    //Only Counts in the Write And Sector Erase Operation;				begin					if (CountStep<(Delay_WE_P+Delay_WE_PH-1))						CountStep<=CountStep+1;					else						CountStep<=4'b0000;				end		end																//Control Block,控制模块,根据主端输入控制接口操作		always @(posedge CLK or negedge RST_N )			begin				if (RST_N == 0)					begin									DataValid_N<=1;       //Data Not Valid;						DataIdle_N<=0;        //DataBus Idle, OK to write New datas;						Adr_temp<=21'h000000;						DataOut_h<=32'h00000000;						CE_s<=0;						OE_s<=0;						WE_s<=0;						Data_temp<=16'hZ;						Adr_s<=21'hZ;						Busy<=0;					end									else if ((CE_h==0)&&(SecEr==1)&&(OE_h==1)&&(WE_h==0))         //Sector Erase,Sector Erase操作;					begin                 //Controlled by WE_s;						CE_s<=0;						OE_s<=1;						if ((CountStep<Delay_WE_P)&&(CountWE<4'b1100))							WE_s<=0;						else							WE_s<=1;												//Control the Sequences Load of the Sector Erase;							case (CountWE+1)							4'b0001: Adr_s<=21'h5555;            //First Word's Address;							4'b0010: Data_temp<=16'hXXAA;							4'b0011: Adr_s<=21'h2AAA;            //Second Word's Address;														4'b0100: Data_temp<=16'hXX55;							4'b0101: Adr_s<=21'h5555;            //Third Word's Address;							4'b0110: Data_temp<=16'hXX80;							4'b0111: Adr_s<=21'h5555;            //Forth Word's Address;							4'b1000: Data_temp<=16'hXXAA;							4'b1001: Adr_s<=21'h2AAA;            //Fifth Word's Address;							4'b1010: Data_temp<=16'hXX55;							4'b1011: Adr_s[20:11]<=Adr_h[20:11];               //Sector Address;							4'b1100: Data_temp<=16'hXX30;						endcase					end													//Program Operation;				else if ((CE_h==0)&&(SecEr==0)&&(OE_h==1)&&(WE_h==0)&&(Count_1us<=8'h01))					begin						CE_s<=0;						OE_s<=1;						if ((CountStep<Delay_WE_P)&&(CountWE<4'b1000))							WE_s<=0;						else							WE_s<=1;												//Control the Sequences Load of the Sector Erase;							case (CountWE+1)							4'b0001: Adr_s<=21'h5555;            //First Word's Address;							4'b0010: Data_temp<=16'hXXAA;							4'b0011: Adr_s<=21'h2AAA;            //Second Word's Address;							4'b0100: Data_temp<=16'hXX55;							4'b0101: Adr_s<=21'h5555;            //Third Word's Address;							4'b0110: Data_temp<=16'hXXA0;							4'b0111:								begin										if (Adr_temp!=Adr_h)										begin											Adr_s<=Adr_h;               //Input Word's Address;											if (CountStep==4'b0000)												Adr_temp<=Adr_h;										end									else if (Adr_temp==Adr_h)										Adr_s<=Adr_h+1;								end							4'b1000:								begin									Busy<=1;									if (Adr_temp!=Adr_h)										begin											Data_temp<=DataIn_h[15:0];											DQ7_Temp<=DataIn_h[7];										end									else if (Adr_temp==Adr_h)										begin											Data_temp<=DataIn_h[31:16];											DQ7_Temp<=DataIn_h[22];										end																end						endcase												if (Count_1us==8'b01100100)							begin								if (DQ7_Temp==Data_s[7])									begin										Busy<=0;										DataIdle_N<=0;									end								else									begin										Busy<=1;										DataIdle_N<=1;									end							end					end									//Read Operation				else if ((CE_h==0)&&(OE_h==0)&&(WE_h==0))					begin						CE_s<=0;						OE_s<=0;						WE_s<=0;						if(FlashRead_N==0)  //Read OPeration Permitted and Time is OK;							begin								if(!ReadCtrl)								   begin								      Adr_s<=Adr_h;								      DataOut_h[15:0]<=Data_s;								      DataValid_N<=1;								   end								else if(ReadCtrl)									begin									  Adr_s<=Adr_h+1;										DataOut_h[31:16]<=Data_s;    //是否考虑此处产生的锁存器?										DataValid_N<=0;                //Data is Valid;数据有效									end							end					end				else					begin						CE_s<=1;					end			end				//Inout Port Data Process;双向端口数据处理		assign Data_s = ((OE_h==1)&&(WE_h==0)) ?  Data_temp : 16'hZZZZ ;				//1us Counter;1us计数器;		always @(posedge CLK or negedge RST_N)			begin				if (!RST_N)					Count_1us<=8'b00000000;				else if (CountWE==4'b1000)					if (Count_1us<Delay_1us)						Count_1us<=Count_1us+1;					else						Count_1us<=8'b00000000;			end							//对WE的翻转进行计数,便于控制时间		always @(WE_s)			begin				if ((CE_s==0)&&(SecEr==1)&&(OE_s==1))					begin						if (CountWE<4'b1100)							CountWE<=CountWE+1;						else							CountWE<=4'b0000;					end				else if ((CE_s==0)&&(SecEr==0)&&(OE_s==1))					begin						if (CountWE<4'b1000)							CountWE<=CountWE+1;						else							CountWE<=4'b0000;					end			endendmodule

⌨️ 快捷键说明

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