| |
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
/2