| |
W25Q128全擦除实验,
TRIG我映射到了开发板的按键,只打了拍子,没有进行消抖。
module SPI_FLASH
(
	SCK,
	CSB,
	MOSI,
	
	CLK,
	RSTB,
	
	TRIG
);
output 	reg	SCK;
output 	reg     CSB;
output 	reg	MOSI;
	
input	wire	CLK;
input	wire	RSTB;
	
input	wire	TRIG;
parameter	IDLE = 3'b000;
parameter	WREN = 3'b001;
parameter	WAIT = 3'b010;
parameter  	BE   = 3'b011;
parameter	DONE = 3'b100;
reg     [7:0]   DATA; 
reg     [2:0]	DIV_CNT;
reg     [2:0]	CNT_100NS;
reg	[3:0]	CNT_BIT;
reg	[1:0]	CNT_BYTE;
reg	[2:0]	NST,PST;
reg 		START;
reg  TRIG_1P,TRIG_2P,TRIG_3P;
always@(posedge CLK or negedge RSTB)begin
	if(!RSTB)begin
		{TRIG_1P,TRIG_2P,TRIG_3P} <= 3'b0;
	end else begin
		{TRIG_1P,TRIG_2P,TRIG_3P} <= {TRIG,TRIG_1P,TRIG_2P};
	end
end
wire TRIG_RISE  =  TRIG_2P & !TRIG_3P;
always@(posedge CLK or negedge RSTB)begin
	if(!RSTB)begin
		START <= 1'b0;
	end else if(NST == DONE) begin
		START <= 1'b0;
	end else if(TRIG_RISE) begin
		START <= 1'b1;
	end
end
wire DIV_CNT_FULL = (DIV_CNT >= 3'h3);
wire DIV_CNT_HALF = (DIV_CNT == 3'h1);
always@(posedge CLK or negedge RSTB)begin
	if(!RSTB)
		DIV_CNT <= 3'b0;
	else if(NST == WAIT)
		DIV_CNT <= 3'h0;
	else if(DIV_CNT_FULL)
		DIV_CNT <= 3'h0;
	else if(NST == WREN || NST == BE)
		DIV_CNT <= DIV_CNT + 1'b1;
end
wire CNT_BIT_FULL = (CNT_BIT >= 4'h7);
always@(posedge CLK or negedge RSTB)begin
	if(!RSTB)
		CNT_BIT <= 4'h0;
	else if(DIV_CNT_FULL&&CNT_BIT_FULL)
		CNT_BIT <= 4'h0;
	else if((NST == WREN || NST == BE ) && DIV_CNT_FULL)
		CNT_BIT <= CNT_BIT + 1'b1;
end
wire CNT_BYTE_FULL = (CNT_BYTE >= 2'h1);
always@(posedge CLK or negedge RSTB)begin
	if(!RSTB)
		CNT_BYTE <= 4'h0;
	else if(DIV_CNT_FULL&&CNT_BIT_FULL&&CNT_BYTE_FULL)
		CNT_BYTE <= 4'h0;
	else if((NST == WREN || NST == BE ) && CNT_BIT_FULL)
		CNT_BYTE <= CNT_BYTE + 1'b1;
end
wire CNT_100NS_FULL = (CNT_100NS > 3'h5);
always@(posedge CLK or negedge RSTB)begin
	if(!RSTB)
		CNT_100NS <= 4'h0;
	else if(CNT_100NS_FULL)
		CNT_100NS <= 4'h0;
	else if(PST == WAIT)
		CNT_100NS <= CNT_100NS + 1'b1;
end
always@(posedge CLK or negedge RSTB)begin
	if(!RSTB)
		DATA <= 8'h00;
	else if(NST == WREN)
		DATA <= 8'b0000_0110;
	else if(NST == BE )
		DATA <= 8'b1100_0111;
end
always@(posedge CLK or negedge RSTB)begin
	if(!RSTB)
		SCK <= 1'b0;
	else if(DIV_CNT_HALF)
		SCK <= 1'b1;
	else if(DIV_CNT_FULL)
		SCK <= 1'b0;
	else if (NST == DONE)
		SCK <= 1'b0;
end
always@(posedge CLK or negedge RSTB)begin
	if(!RSTB)
		CSB <= 1'b1;
	else if((NST == WREN)||((NST == BE)&&CNT_100NS_FULL))
		CSB <= 1'b0;
	else if(PST == WAIT | PST == DONE)
		CSB <= 1'b1;
end
always@(posedge CLK or negedge RSTB)begin
	if(!RSTB)
		PST <= 3'b000;
	else
		PST <= NST;
end
always@(posedge CLK or negedge RSTB)begin
	if(!RSTB)
		MOSI <= 1'b0;
	else if(DIV_CNT == 3'h1)
		MOSI <= DATA[7-CNT_BIT];
	else if(NST == IDLE)
		MOSI <= 1'b0;
end
always@(*)begin
	NST = PST;
	case(PST)
		IDLE : begin
			if(START)
				NST = WREN;
			else 
				NST = IDLE;
		end
		WREN : begin
			if(DIV_CNT_FULL&&CNT_BIT_FULL&&CNT_BYTE_FULL)
				NST = WAIT;
			else 
				NST = WREN;
		end
		WAIT : begin
			if(CNT_100NS_FULL)
				NST = BE;
			else 
				NST = WAIT;
		end
		BE : begin
			if(DIV_CNT_FULL&&CNT_BIT_FULL&&CNT_BYTE_FULL)
				NST = DONE;
			else
				NST = BE;
		end
		DONE:begin
			NST = IDLE;
		end
		default : NST = IDLE;
	
	endcase
end
endmodule /1
 /1 